diff --git a/.tx/config b/.tx/config index e4d1fc65732..74875508f29 100644 --- a/.tx/config +++ b/.tx/config @@ -236,6 +236,18 @@ source_file = htdocs/langs/en_US/paypal.lang source_lang = en_US type = MOZILLAPROPERTIES +[dolibarr.printgcp] +file_filter = htdocs/langs//printgcp.lang +source_file = htdocs/langs/en_US/printgcp.lang +source_lang = en_US +type = MOZILLAPROPERTIES + +[dolibarr.printing] +file_filter = htdocs/langs//printing.lang +source_file = htdocs/langs/en_US/printing.lang +source_lang = en_US +type = MOZILLAPROPERTIES + [dolibarr.printipp] file_filter = htdocs/langs//printipp.lang source_file = htdocs/langs/en_US/printipp.lang diff --git a/COPYRIGHT b/COPYRIGHT index 2e1c6e921b9..c6a629c5c7a 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -52,6 +52,9 @@ http://www.fsf.org/licensing/licenses/index_html Copyright --------- +Copyright (C) 2015 +- Marcos García + Copyright (C) 2014 - Laurent Destailleur - Raphaël Doursenaud diff --git a/ChangeLog b/ChangeLog index 0f4f3b83a1c..9e9fb51ab84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -196,6 +196,18 @@ Dolibarr better: - Fix: ref_ext was not saved when recording a customer order from web service - Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid. - Fix: withdrawal create error if in the same month are deleted previus withdrawals. +- Fix: [ bug #1788 ] Duplicated doActions hook in product/fournisseurs.php +- Fix: withdrawal create error if in the same month are deleted previus withdrawals. +- Fix: [ bug #1801 ] FAC_FORCE_DATE_VALIDATION constant alters supplier invoice date given to numeration modules +- Fix: [ bug #1802 ] SQL error when updating a task with PostgreSQL database +- Fix: [ bug #1785 ] Start date is lost in Project > Linked objects +- Fix: [ bug #1804 ] SQL error when sending email without addresee +- Fix: [ bug #1803 ] AJAX company contact input is not aligned +- Fix: [ bug #1787 ] Incorrect behaviour of doActions hook +- Fix: [ bug #1796 ] Unable to use numeration modules from an external module +- Fix: [ bug #1783 ] SQL error when enabling 3rd party module with PostgreSQL and MySQL strict mode ON +- Fix: [ bug #1717 ] Sorting unpaid invoices by amount received brings due amount +- Fix: [ bug #1784 ] MOTD doesn't show up in Amarok theme ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. @@ -360,6 +372,8 @@ Fix: Paypal link were broken dur to SSL v3 closed. Fix: [ bug #1769 ] Error when installing to a PostgreSQL DB that contains numbers Fix: [ bug #1752 ] Date filter of margins module, filters since 12H instead of 00H Fix: [ bug #1757 ] Sorting breaks product/service statistics +Fix: [ bug #1797 ] Tulip supplier invoice module takes creation date instead of invoice date +Fix: [ bug #1792 ] Users are not allowed to see margins module index page when no product view permission is enabled ***** ChangeLog for 3.5.6 compared to 3.5.5 ***** Fix: Avoid missing class error for fetch_thirdparty method #1973 diff --git a/build/makepack-howto.txt b/build/makepack-howto.txt index 40b0e5180bc..9e5004f4ba7 100644 --- a/build/makepack-howto.txt +++ b/build/makepack-howto.txt @@ -11,7 +11,6 @@ beta version of Dolibarr, step by step. - Update version/info in /ChangeLog - Update version number with x.y.z-w in htdocs/filefunc.inc.php - Update version number with x.y.z-w in build/debian/changelog -- Update version number with x.y.z-w in build/exe/doliwamp/doliwamp.iss - Update version number with x.y.z-w in build/rpm/*.spec - Commit all changes. - Add a Tag (x.y.betaz_YYYYMMDD) and push it: git push --tags @@ -30,10 +29,9 @@ This files describe steps made by Dolibarr packaging team to make a complete release of Dolibarr, step by step. - Check all files are commited. -- Update version/info in ChangeLog +- Update version/info in ChangeLog. To generate a changelog, you can do "git log x.y.z..HEAD --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^Fix\|New\|Sec'" - Update version number with x.y.z in htdocs/filefunc.inc.php - Update version number with x.y.z in build/debian/changelog -- Update version number with x.y.z in build/exe/doliwamp/doliwamp.iss - Update version number with x.y.z in build/rpm/*.spec - Commit all changes. diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index a4463766278..478f1c9e1cd 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -119,571 +119,573 @@ $parameters=array('rowid'=>$rowid, 'objcanvas'=>$objcanvas); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer)) +if (empty($reshook)) { - $error=0; - if (empty($user->rights->user->user->creer)) // If can edit only itself user, we can link to itself only + if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer)) { - if ($userid != $user->id && $userid != $object->user_id) + $error=0; + if (empty($user->rights->user->user->creer)) // If can edit only itself user, we can link to itself only { - $error++; - setEventMessage($langs->trans("ErrorUserPermissionAllowsToLinksToItselfOnly"), 'errors'); - } - } - - if (! $error) - { - if ($userid != $object->user_id) // If link differs from currently in database - { - $result=$object->setUserId($userid); - if ($result < 0) dol_print_error($object->db,$object->error); - $action=''; - } - } -} - -if ($action == 'setsocid') -{ - $error=0; - if (! $error) - { - if ($socid != $object->fk_soc) // If link differs from currently in database - { - $sql ="SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; - $sql.=" WHERE fk_soc = '".$socid."'"; - $sql.=" AND entity = ".$conf->entity; - $resql = $db->query($sql); - if ($resql) + if ($userid != $user->id && $userid != $object->user_id) { - $obj = $db->fetch_object($resql); - if ($obj && $obj->rowid > 0) - { - $othermember=new Adherent($db); - $othermember->fetch($obj->rowid); - $thirdparty=new Societe($db); - $thirdparty->fetch($socid); - $error++; - setEventMessage($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty",$othermember->getFullName($langs),$othermember->login,$thirdparty->name), 'errors'); - } + $error++; + setEventMessage($langs->trans("ErrorUserPermissionAllowsToLinksToItselfOnly"), 'errors'); } + } - if (! $error) + if (! $error) + { + if ($userid != $object->user_id) // If link differs from currently in database { - $result=$object->setThirdPartyId($socid); + $result=$object->setUserId($userid); if ($result < 0) dol_print_error($object->db,$object->error); $action=''; } } } -} -// Create user from a member -if ($action == 'confirm_create_user' && $confirm == 'yes' && $user->rights->user->user->creer) -{ - if ($result > 0) + if ($action == 'setsocid') { - // Creation user - $nuser = new User($db); - $result=$nuser->create_from_member($object,GETPOST('login')); - - if ($result < 0) + $error=0; + if (! $error) { - $langs->load("errors"); - setEventMessage($langs->trans($nuser->error), 'errors'); - } - } - else - { - setEventMessage($object->error, 'errors'); - } -} - -// Create third party from a member -if ($action == 'confirm_create_thirdparty' && $confirm == 'yes' && $user->rights->societe->creer) -{ - if ($result > 0) - { - // Creation user - $company = new Societe($db); - $result=$company->create_from_member($object,GETPOST('companyname')); - - if ($result < 0) - { - $langs->load("errors"); - setEventMessage($langs->trans($company->error), 'errors'); - setEventMessage($company->errors, 'errors'); - } - } - else - { - setEventMessage($object->error, 'errors'); - } -} - -if ($action == 'confirm_sendinfo' && $confirm == 'yes') -{ - if ($object->email) - { - $from=$conf->email_from; - if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM; - - $result=$object->send_an_email($langs->transnoentitiesnoconv("ThisIsContentOfYourCard")."\n\n%INFOS%\n\n",$langs->transnoentitiesnoconv("CardContent")); - - $langs->load("mails"); - setEventMessage($langs->trans("MailSuccessfulySent", $from, $object->email)); - } -} - -if ($action == 'update' && ! $_POST["cancel"] && $user->rights->adherent->creer) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $birthdate=''; - if (isset($_POST["birthday"]) && $_POST["birthday"] - && isset($_POST["birthmonth"]) && $_POST["birthmonth"] - && isset($_POST["birthyear"]) && $_POST["birthyear"]) - { - $birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]); - } - $lastname=$_POST["lastname"]; - $firstname=$_POST["firstname"]; - $morphy=$morphy=$_POST["morphy"];; - if ($morphy != 'mor' && empty($lastname)) { - $error++; - $langs->load("errors"); - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname")), 'errors'); - } - if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) { - $error++; - $langs->load("errors"); - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname")), 'errors'); - } - - // Create new object - if ($result > 0 && ! $error) - { - $object->oldcopy=dol_clone($object); - - // Change values - $object->civility_id = trim($_POST["civility_id"]); - $object->firstname = trim($_POST["firstname"]); - $object->lastname = trim($_POST["lastname"]); - $object->login = trim($_POST["login"]); - $object->pass = trim($_POST["pass"]); - - $object->societe = trim($_POST["societe"]); - $object->company = trim($_POST["societe"]); - - $object->address = trim($_POST["address"]); - $object->zip = trim($_POST["zipcode"]); - $object->town = trim($_POST["town"]); - $object->state_id = $_POST["state_id"]; - $object->country_id = $_POST["country_id"]; - - $object->phone = trim($_POST["phone"]); - $object->phone_perso = trim($_POST["phone_perso"]); - $object->phone_mobile= trim($_POST["phone_mobile"]); - $object->email = trim($_POST["email"]); - $object->skype = trim($_POST["skype"]); - $object->birth = $birthdate; - - $object->typeid = $_POST["typeid"]; - //$object->note = trim($_POST["comment"]); - $object->morphy = $_POST["morphy"]; - - if (GETPOST('deletephoto')) $object->photo=''; - elseif (! empty($_FILES['photo']['name'])) $object->photo = dol_sanitizeFileName($_FILES['photo']['name']); - - // Get status and public property - $object->statut = $_POST["statut"]; - $object->public = $_POST["public"]; - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - - // Check if we need to also synchronize user information - $nosyncuser=0; - if ($object->user_id) // If linked to a user - { - if ($user->id != $object->user_id && empty($user->rights->user->user->creer)) $nosyncuser=1; // Disable synchronizing - } - - // Check if we need to also synchronize password information - $nosyncuserpass=0; - if ($object->user_id) // If linked to a user - { - if ($user->id != $object->user_id && empty($user->rights->user->user->password)) $nosyncuserpass=1; // Disable synchronizing - } - - $result=$object->update($user,0,$nosyncuser,$nosyncuserpass); - if ($result >= 0 && ! count($object->errors)) - { - // Logo/Photo save - $dir= $conf->adherent->dir_output . '/' . get_exdir($object->id,2,0,1).'/photos'; - $file_OK = is_uploaded_file($_FILES['photo']['tmp_name']); - if ($file_OK) + if ($socid != $object->fk_soc) // If link differs from currently in database { - if (GETPOST('deletephoto')) + $sql ="SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; + $sql.=" WHERE fk_soc = '".$socid."'"; + $sql.=" AND entity = ".$conf->entity; + $resql = $db->query($sql); + if ($resql) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileimg=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/'.$object->photo; - $dirthumbs=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/thumbs'; - dol_delete_file($fileimg); - dol_delete_dir_recursive($dirthumbs); + $obj = $db->fetch_object($resql); + if ($obj && $obj->rowid > 0) + { + $othermember=new Adherent($db); + $othermember->fetch($obj->rowid); + $thirdparty=new Societe($db); + $thirdparty->fetch($socid); + $error++; + setEventMessage($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty",$othermember->getFullName($langs),$othermember->login,$thirdparty->name), 'errors'); + } } - if (image_format_supported($_FILES['photo']['name']) > 0) + if (! $error) { - dol_mkdir($dir); + $result=$object->setThirdPartyId($socid); + if ($result < 0) dol_print_error($object->db,$object->error); + $action=''; + } + } + } + } - if (@is_dir($dir)) + // Create user from a member + if ($action == 'confirm_create_user' && $confirm == 'yes' && $user->rights->user->user->creer) + { + if ($result > 0) + { + // Creation user + $nuser = new User($db); + $result=$nuser->create_from_member($object,GETPOST('login')); + + if ($result < 0) + { + $langs->load("errors"); + setEventMessage($langs->trans($nuser->error), 'errors'); + } + } + else + { + setEventMessage($object->error, 'errors'); + } + } + + // Create third party from a member + if ($action == 'confirm_create_thirdparty' && $confirm == 'yes' && $user->rights->societe->creer) + { + if ($result > 0) + { + // Creation user + $company = new Societe($db); + $result=$company->create_from_member($object,GETPOST('companyname')); + + if ($result < 0) + { + $langs->load("errors"); + setEventMessage($langs->trans($company->error), 'errors'); + setEventMessage($company->errors, 'errors'); + } + } + else + { + setEventMessage($object->error, 'errors'); + } + } + + if ($action == 'confirm_sendinfo' && $confirm == 'yes') + { + if ($object->email) + { + $from=$conf->email_from; + if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM; + + $result=$object->send_an_email($langs->transnoentitiesnoconv("ThisIsContentOfYourCard")."\n\n%INFOS%\n\n",$langs->transnoentitiesnoconv("CardContent")); + + $langs->load("mails"); + setEventMessage($langs->trans("MailSuccessfulySent", $from, $object->email)); + } + } + + if ($action == 'update' && ! $_POST["cancel"] && $user->rights->adherent->creer) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $birthdate=''; + if (isset($_POST["birthday"]) && $_POST["birthday"] + && isset($_POST["birthmonth"]) && $_POST["birthmonth"] + && isset($_POST["birthyear"]) && $_POST["birthyear"]) + { + $birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]); + } + $lastname=$_POST["lastname"]; + $firstname=$_POST["firstname"]; + $morphy=$morphy=$_POST["morphy"];; + if ($morphy != 'mor' && empty($lastname)) { + $error++; + $langs->load("errors"); + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname")), 'errors'); + } + if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) { + $error++; + $langs->load("errors"); + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname")), 'errors'); + } + + // Create new object + if ($result > 0 && ! $error) + { + $object->oldcopy=dol_clone($object); + + // Change values + $object->civility_id = trim($_POST["civility_id"]); + $object->firstname = trim($_POST["firstname"]); + $object->lastname = trim($_POST["lastname"]); + $object->login = trim($_POST["login"]); + $object->pass = trim($_POST["pass"]); + + $object->societe = trim($_POST["societe"]); + $object->company = trim($_POST["societe"]); + + $object->address = trim($_POST["address"]); + $object->zip = trim($_POST["zipcode"]); + $object->town = trim($_POST["town"]); + $object->state_id = $_POST["state_id"]; + $object->country_id = $_POST["country_id"]; + + $object->phone = trim($_POST["phone"]); + $object->phone_perso = trim($_POST["phone_perso"]); + $object->phone_mobile= trim($_POST["phone_mobile"]); + $object->email = trim($_POST["email"]); + $object->skype = trim($_POST["skype"]); + $object->birth = $birthdate; + + $object->typeid = $_POST["typeid"]; + //$object->note = trim($_POST["comment"]); + $object->morphy = $_POST["morphy"]; + + if (GETPOST('deletephoto')) $object->photo=''; + elseif (! empty($_FILES['photo']['name'])) $object->photo = dol_sanitizeFileName($_FILES['photo']['name']); + + // Get status and public property + $object->statut = $_POST["statut"]; + $object->public = $_POST["public"]; + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + + // Check if we need to also synchronize user information + $nosyncuser=0; + if ($object->user_id) // If linked to a user + { + if ($user->id != $object->user_id && empty($user->rights->user->user->creer)) $nosyncuser=1; // Disable synchronizing + } + + // Check if we need to also synchronize password information + $nosyncuserpass=0; + if ($object->user_id) // If linked to a user + { + if ($user->id != $object->user_id && empty($user->rights->user->user->password)) $nosyncuserpass=1; // Disable synchronizing + } + + $result=$object->update($user,0,$nosyncuser,$nosyncuserpass); + if ($result >= 0 && ! count($object->errors)) + { + // Logo/Photo save + $dir= $conf->adherent->dir_output . '/' . get_exdir($object->id,2,0,1).'/photos'; + $file_OK = is_uploaded_file($_FILES['photo']['tmp_name']); + if ($file_OK) + { + if (GETPOST('deletephoto')) { - $newfile=$dir.'/'.dol_sanitizeFileName($_FILES['photo']['name']); - if (! dol_move_uploaded_file($_FILES['photo']['tmp_name'],$newfile,1,0,$_FILES['photo']['error']) > 0) - { - setEventMessage($langs->trans("ErrorFailedToSaveFile"), 'errors'); - } - else - { - // Create small thumbs for company (Ratio is near 16/9) - // Used on logon for example - $imgThumbSmall = vignette($newfile, $maxwidthsmall, $maxheightsmall, '_small', $quality); + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + $fileimg=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/'.$object->photo; + $dirthumbs=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/thumbs'; + dol_delete_file($fileimg); + dol_delete_dir_recursive($dirthumbs); + } - // Create mini thumbs for company (Ratio is near 16/9) - // Used on menu or for setup page for example - $imgThumbMini = vignette($newfile, $maxwidthmini, $maxheightmini, '_mini', $quality); + if (image_format_supported($_FILES['photo']['name']) > 0) + { + dol_mkdir($dir); + + if (@is_dir($dir)) + { + $newfile=$dir.'/'.dol_sanitizeFileName($_FILES['photo']['name']); + if (! dol_move_uploaded_file($_FILES['photo']['tmp_name'],$newfile,1,0,$_FILES['photo']['error']) > 0) + { + setEventMessage($langs->trans("ErrorFailedToSaveFile"), 'errors'); + } + else + { + // Create small thumbs for company (Ratio is near 16/9) + // Used on logon for example + $imgThumbSmall = vignette($newfile, $maxwidthsmall, $maxheightsmall, '_small', $quality); + + // Create mini thumbs for company (Ratio is near 16/9) + // Used on menu or for setup page for example + $imgThumbMini = vignette($newfile, $maxwidthmini, $maxheightmini, '_mini', $quality); + } } } + else + { + setEventMessage("ErrorBadImageFormat", 'errors'); + } } else { - setEventMessage("ErrorBadImageFormat", 'errors'); + switch($_FILES['photo']['error']) + { + case 1: //uploaded file exceeds the upload_max_filesize directive in php.ini + case 2: //uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form + $errors[] = "ErrorFileSizeTooLarge"; + break; + case 3: //uploaded file was only partially uploaded + $errors[] = "ErrorFilePartiallyUploaded"; + break; + } + } + + $rowid=$object->id; + $action=''; + + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; } } else { - switch($_FILES['photo']['error']) - { - case 1: //uploaded file exceeds the upload_max_filesize directive in php.ini - case 2: //uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form - $errors[] = "ErrorFileSizeTooLarge"; - break; - case 3: //uploaded file was only partially uploaded - $errors[] = "ErrorFilePartiallyUploaded"; - break; + if ($object->error) { + setEventMessage($object->error, 'errors'); + } else { + setEventMessage($object->errors, 'errors'); + } + $action=''; + } + } + else + { + $action='edit'; + } + } + + if ($action == 'add' && $user->rights->adherent->creer) + { + if ($canvas) $object->canvas=$canvas; + $birthdate=''; + if (isset($_POST["birthday"]) && $_POST["birthday"] + && isset($_POST["birthmonth"]) && $_POST["birthmonth"] + && isset($_POST["birthyear"]) && $_POST["birthyear"]) + { + $birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]); + } + $datecotisation=''; + if (isset($_POST["reday"]) && isset($_POST["remonth"]) && isset($_POST["reyear"])) + { + $datecotisation=dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]); + } + + $typeid=$_POST["typeid"]; + $civility_id=$_POST["civility_id"]; + $lastname=$_POST["lastname"]; + $firstname=$_POST["firstname"]; + $societe=$_POST["societe"]; + $address=$_POST["address"]; + $zip=$_POST["zipcode"]; + $town=$_POST["town"]; + $state_id=$_POST["state_id"]; + $country_id=$_POST["country_id"]; + + $phone=$_POST["phone"]; + $phone_perso=$_POST["phone_perso"]; + $phone_mobile=$_POST["phone_mobile"]; + $skype=$_POST["member_skype"]; + $email=$_POST["member_email"]; + $login=$_POST["member_login"]; + $pass=$_POST["password"]; + $photo=$_POST["photo"]; + //$comment=$_POST["comment"]; + $morphy=$_POST["morphy"]; + $cotisation=$_POST["cotisation"]; + $public=$_POST["public"]; + + $userid=$_POST["userid"]; + $socid=$_POST["socid"]; + + $object->civility_id = $civility_id; + $object->firstname = $firstname; + $object->lastname = $lastname; + $object->societe = $societe; + $object->address = $address; + $object->zip = $zip; + $object->town = $town; + $object->state_id = $state_id; + $object->country_id = $country_id; + $object->phone = $phone; + $object->phone_perso = $phone_perso; + $object->phone_mobile= $phone_mobile; + $object->skype = $skype; + $object->email = $email; + $object->login = $login; + $object->pass = $pass; + $object->birth = $birthdate; + $object->photo = $photo; + $object->typeid = $typeid; + //$object->note = $comment; + $object->morphy = $morphy; + $object->user_id = $userid; + $object->fk_soc = $socid; + $object->public = $public; + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + + // Check parameters + if (empty($morphy) || $morphy == "-1") { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Nature")), 'errors'); + } + // Test si le login existe deja + if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) + { + if (empty($login)) { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Login")), 'errors'); + } + else { + $sql = "SELECT login FROM ".MAIN_DB_PREFIX."adherent WHERE login='".$db->escape($login)."'"; + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + } + if ($num) { + $error++; + $langs->load("errors"); + setEventMessage($langs->trans("ErrorLoginAlreadyExists",$login), 'errors'); } } + if (empty($pass)) { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Password")), 'errors'); + } + } + if ($morphy != 'mor' && empty($lastname)) { + $error++; + $langs->load("errors"); + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname")), 'errors'); + } + if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) { + $error++; + $langs->load("errors"); + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname")), 'errors'); + } + if (! ($typeid > 0)) { // Keep () before ! + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); + } + if ($conf->global->ADHERENT_MAIL_REQUIRED && ! isValidEMail($email)) { + $error++; + $langs->load("errors"); + setEventMessage($langs->trans("ErrorBadEMail",$email), 'errors'); + } + $public=0; + if (isset($public)) $public=1; - $rowid=$object->id; - $action=''; + if (! $error) + { + $db->begin(); + // Email a peu pres correct et le login n'existe pas + $result=$object->create($user); + if ($result > 0) + { + $db->commit(); + $rowid=$object->id; + $action=''; + } + else + { + $db->rollback(); + + if ($object->error) { + setEventMessage($object->error, 'errors'); + } else { + setEventMessage($object->errors, 'errors'); + } + + $action = 'create'; + } + } + else { + $action = 'create'; + } + } + + if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes') + { + $result=$object->delete($rowid); + if ($result > 0) + { if (! empty($backtopage)) { header("Location: ".$backtopage); exit; } + else + { + header("Location: list.php"); + exit; + } } else { + $errmesg=$object->error; + } + } + + if ($user->rights->adherent->creer && $action == 'confirm_valid' && $confirm == 'yes') + { + $error=0; + + $db->begin(); + + $adht = new AdherentType($db); + $adht->fetch($object->typeid); + + $result=$object->validate($user); + + if ($result >= 0 && ! count($object->errors)) + { + // Send confirmation Email (selon param du type adherent sinon generique) + if ($object->email && GETPOST("send_mail")) + { + $result=$object->send_an_email($adht->getMailOnValid(),$conf->global->ADHERENT_MAIL_VALID_SUBJECT,array(),array(),array(),"","",0,2); + if ($result < 0) + { + $error++; + setEventMessage($object->error, 'errors'); + } + } + } + else + { + $error++; if ($object->error) { setEventMessage($object->error, 'errors'); } else { setEventMessage($object->errors, 'errors'); } - $action=''; } - } - else - { - $action='edit'; - } -} -if ($action == 'add' && $user->rights->adherent->creer) -{ - if ($canvas) $object->canvas=$canvas; - $birthdate=''; - if (isset($_POST["birthday"]) && $_POST["birthday"] - && isset($_POST["birthmonth"]) && $_POST["birthmonth"] - && isset($_POST["birthyear"]) && $_POST["birthyear"]) - { - $birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]); - } - $datecotisation=''; - if (isset($_POST["reday"]) && isset($_POST["remonth"]) && isset($_POST["reyear"])) - { - $datecotisation=dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]); - } - - $typeid=$_POST["typeid"]; - $civility_id=$_POST["civility_id"]; - $lastname=$_POST["lastname"]; - $firstname=$_POST["firstname"]; - $societe=$_POST["societe"]; - $address=$_POST["address"]; - $zip=$_POST["zipcode"]; - $town=$_POST["town"]; - $state_id=$_POST["state_id"]; - $country_id=$_POST["country_id"]; - - $phone=$_POST["phone"]; - $phone_perso=$_POST["phone_perso"]; - $phone_mobile=$_POST["phone_mobile"]; - $skype=$_POST["member_skype"]; - $email=$_POST["member_email"]; - $login=$_POST["member_login"]; - $pass=$_POST["password"]; - $photo=$_POST["photo"]; - //$comment=$_POST["comment"]; - $morphy=$_POST["morphy"]; - $cotisation=$_POST["cotisation"]; - $public=$_POST["public"]; - - $userid=$_POST["userid"]; - $socid=$_POST["socid"]; - - $object->civility_id = $civility_id; - $object->firstname = $firstname; - $object->lastname = $lastname; - $object->societe = $societe; - $object->address = $address; - $object->zip = $zip; - $object->town = $town; - $object->state_id = $state_id; - $object->country_id = $country_id; - $object->phone = $phone; - $object->phone_perso = $phone_perso; - $object->phone_mobile= $phone_mobile; - $object->skype = $skype; - $object->email = $email; - $object->login = $login; - $object->pass = $pass; - $object->birth = $birthdate; - $object->photo = $photo; - $object->typeid = $typeid; - //$object->note = $comment; - $object->morphy = $morphy; - $object->user_id = $userid; - $object->fk_soc = $socid; - $object->public = $public; - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - - // Check parameters - if (empty($morphy) || $morphy == "-1") { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Nature")), 'errors'); - } - // Test si le login existe deja - if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) - { - if (empty($login)) { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Login")), 'errors'); - } - else { - $sql = "SELECT login FROM ".MAIN_DB_PREFIX."adherent WHERE login='".$db->escape($login)."'"; - $result = $db->query($sql); - if ($result) { - $num = $db->num_rows($result); - } - if ($num) { - $error++; - $langs->load("errors"); - setEventMessage($langs->trans("ErrorLoginAlreadyExists",$login), 'errors'); - } - } - if (empty($pass)) { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Password")), 'errors'); - } - } - if ($morphy != 'mor' && empty($lastname)) { - $error++; - $langs->load("errors"); - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname")), 'errors'); - } - if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) { - $error++; - $langs->load("errors"); - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname")), 'errors'); - } - if (! ($typeid > 0)) { // Keep () before ! - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); - } - if ($conf->global->ADHERENT_MAIL_REQUIRED && ! isValidEMail($email)) { - $error++; - $langs->load("errors"); - setEventMessage($langs->trans("ErrorBadEMail",$email), 'errors'); - } - $public=0; - if (isset($public)) $public=1; - - if (! $error) - { - $db->begin(); - - // Email a peu pres correct et le login n'existe pas - $result=$object->create($user); - if ($result > 0) + if (! $error) { $db->commit(); - $rowid=$object->id; - $action=''; } else { $db->rollback(); - - if ($object->error) { - setEventMessage($object->error, 'errors'); - } else { - setEventMessage($object->errors, 'errors'); - } - - $action = 'create'; } + $action=''; } - else { - $action = 'create'; - } -} -if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes') -{ - $result=$object->delete($rowid); - if ($result > 0) + if ($user->rights->adherent->supprimer && $action == 'confirm_resign') { - if (! empty($backtopage)) + $error = 0; + + if ($confirm == 'yes') + { + $adht = new AdherentType($db); + $adht->fetch($object->typeid); + + $result=$object->resiliate($user); + + if ($result >= 0 && ! count($object->errors)) + { + if ($object->email && GETPOST("send_mail")) + { + $result=$object->send_an_email($adht->getMailOnResiliate(),$conf->global->ADHERENT_MAIL_RESIL_SUBJECT,array(),array(),array(),"","",0,-1); + } + if ($result < 0) + { + $error++; + setEventMessage($object->error, 'errors'); + } + } + else + { + $error++; + + if ($object->error) { + setEventMessage($object->error, 'errors'); + } else { + setEventMessage($object->errors, 'errors'); + } + $action=''; + } + } + if (! empty($backtopage) && ! $error) { header("Location: ".$backtopage); exit; } - else - { - header("Location: list.php"); - exit; - } } - else + + // SPIP Management + if ($user->rights->adherent->supprimer && $action == 'confirm_del_spip' && $confirm == 'yes') { - $errmesg=$object->error; - } -} - -if ($user->rights->adherent->creer && $action == 'confirm_valid' && $confirm == 'yes') -{ - $error=0; - - $db->begin(); - - $adht = new AdherentType($db); - $adht->fetch($object->typeid); - - $result=$object->validate($user); - - if ($result >= 0 && ! count($object->errors)) - { - // Send confirmation Email (selon param du type adherent sinon generique) - if ($object->email && GETPOST("send_mail")) + if (! count($object->errors)) { - $result=$object->send_an_email($adht->getMailOnValid(),$conf->global->ADHERENT_MAIL_VALID_SUBJECT,array(),array(),array(),"","",0,2); - if ($result < 0) + if (!$mailmanspip->del_to_spip($object)) { - $error++; - setEventMessage($object->error, 'errors'); + setEventMessage($langs->trans('DeleteIntoSpipError').': '.$mailmanspip->error, 'errors'); } } } - else + + if ($user->rights->adherent->creer && $action == 'confirm_add_spip' && $confirm == 'yes') { - $error++; - if ($object->error) { - setEventMessage($object->error, 'errors'); - } else { - setEventMessage($object->errors, 'errors'); - } - } - - if (! $error) - { - $db->commit(); - } - else - { - $db->rollback(); - } - $action=''; -} - -if ($user->rights->adherent->supprimer && $action == 'confirm_resign') -{ - $error = 0; - - if ($confirm == 'yes') - { - $adht = new AdherentType($db); - $adht->fetch($object->typeid); - - $result=$object->resiliate($user); - - if ($result >= 0 && ! count($object->errors)) + if (! count($object->errors)) { - if ($object->email && GETPOST("send_mail")) + if (!$mailmanspip->add_to_spip($object)) { - $result=$object->send_an_email($adht->getMailOnResiliate(),$conf->global->ADHERENT_MAIL_RESIL_SUBJECT,array(),array(),array(),"","",0,-1); + setEventMessage($langs->trans('AddIntoSpipError').': '.$mailmanspip->error, 'errors'); } - if ($result < 0) - { - $error++; - setEventMessage($object->error, 'errors'); - } - } - else - { - $error++; - - if ($object->error) { - setEventMessage($object->error, 'errors'); - } else { - setEventMessage($object->errors, 'errors'); - } - $action=''; - } - } - if (! empty($backtopage) && ! $error) - { - header("Location: ".$backtopage); - exit; - } -} - -// SPIP Management -if ($user->rights->adherent->supprimer && $action == 'confirm_del_spip' && $confirm == 'yes') -{ - if (! count($object->errors)) - { - if (!$mailmanspip->del_to_spip($object)) - { - setEventMessage($langs->trans('DeleteIntoSpipError').': '.$mailmanspip->error, 'errors'); } } } -if ($user->rights->adherent->creer && $action == 'confirm_add_spip' && $confirm == 'yes') -{ - if (! count($object->errors)) - { - if (!$mailmanspip->add_to_spip($object)) - { - setEventMessage($langs->trans('AddIntoSpipError').': '.$mailmanspip->error, 'errors'); - } - } -} - - /* * View diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index b39760c6907..e3908ad19d7 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -65,12 +65,12 @@ if ($action == 'update' && empty($_POST["cancel"])) { dolibarr_set_const($db, "MAIN_DISABLE_ALL_MAILS", GETPOST("MAIN_DISABLE_ALL_MAILS"),'chaine',0,'',$conf->entity); // Send mode parameters - dolibarr_set_const($db, "MAIN_MAIL_SENDMODE", GETPOST("MAIN_MAIL_SENDMODE"),'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_SMTP_PORT"])) dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT"),'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_SMTP_SERVER"])) dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER", GETPOST("MAIN_MAIL_SMTP_SERVER"),'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_SMTPS_ID"])) dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID", GETPOST("MAIN_MAIL_SMTPS_ID"), 'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_SMTPS_PW"])) dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW"), 'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_EMAIL_TLS"])) dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS", GETPOST("MAIN_MAIL_EMAIL_TLS"),'chaine',0,'',0); + dolibarr_set_const($db, "MAIN_MAIL_SENDMODE", GETPOST("MAIN_MAIL_SENDMODE"),'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT"),'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER", GETPOST("MAIN_MAIL_SMTP_SERVER"),'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID", GETPOST("MAIN_MAIL_SMTPS_ID"), 'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW"), 'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS", GETPOST("MAIN_MAIL_EMAIL_TLS"),'chaine',0,'',$conf->entity); // Content parameters dolibarr_set_const($db, "MAIN_MAIL_EMAIL_FROM", GETPOST("MAIN_MAIL_EMAIL_FROM"), 'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_MAIL_ERRORS_TO", GETPOST("MAIN_MAIL_ERRORS_TO"), 'chaine',0,'',$conf->entity); diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 31cad75cffd..0934e42db1f 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -118,6 +118,13 @@ class ActionComm extends CommonObject $error=0; $now=dol_now(); + // Check parameters + if (empty($this->userownerid)) + { + $this->errors[]='ErrorPropertyUserowneridNotDefined'; + return -1; + } + // Clean parameters $this->label=dol_trunc(trim($this->label),128); $this->location=dol_trunc(trim($this->location),128); @@ -147,8 +154,9 @@ class ActionComm extends CommonObject $userownerid=$this->userownerid; $userdoneid=$this->userdoneid; - // Be sure assigned user array is not empty. - if (count($this->userassigned) == 0) $this->userassigned[] = array('id'=>$userownerid); + // Be sure assigned user is defined as an array of array('id'=>,'mandatory'=>,...). + if (empty($this->userassigned) || count($this->userassigned) == 0 || ! is_array($this->userassigned)) + $this->userassigned = array($userownerid=>array('id'=>$userownerid)); if (! $this->type_id || ! $this->type_code) { @@ -235,6 +243,12 @@ class ActionComm extends CommonObject { foreach($this->userassigned as $key => $val) { + if (! is_array($val)) // For backward compatibility when valid + { + $tmpid=$val; + $val=array('id'=>$val); + } + $sql ="INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; $sql.=" VALUES(".$this->id.", 'user', ".$val['id'].", ".($val['mandatory']?$val['mandatory']:'0').", ".($val['transparency']?$val['transparency']:'0').", ".($val['answer_status']?$val['answer_status']:'0').")"; diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index ecb171c6570..a775408e9a8 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -66,6 +66,7 @@ $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="nom"; +$cancelbutton = GETPOST('cancel'); // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $hookmanager->initHooks(array('commcard','globalcard')); @@ -80,12 +81,14 @@ $parameters = array('socid' => $id); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -//Some actions show a "cancel" input submit button with name="cancel" -$cancelbutton = GETPOST('cancel'); - -if ($action == 'setcustomeraccountancycode') +if (empty($reshook)) { - if (! $cancelbutton) + if ($cancelbutton) + { + $action=""; + } + + if ($action == 'setcustomeraccountancycode') { $result=$object->fetch($id); $object->code_compta=$_POST["customeraccountancycode"]; @@ -95,56 +98,52 @@ if ($action == 'setcustomeraccountancycode') setEventMessage($object->errors, 'errors'); } } - $action=""; -} -// conditions de reglement -if ($action == 'setconditions' && $user->rights->societe->creer) -{ - $object->fetch($id); - $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int')); - if ($result < 0) dol_print_error($db,$object->error); -} + // conditions de reglement + if ($action == 'setconditions' && $user->rights->societe->creer) + { + $object->fetch($id); + $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int')); + if ($result < 0) dol_print_error($db,$object->error); + } -// mode de reglement -if ($action == 'setmode' && $user->rights->societe->creer) -{ - $object->fetch($id); - $result=$object->setPaymentMethods(GETPOST('mode_reglement_id','int')); - if ($result < 0) dol_print_error($db,$object->error); -} + // mode de reglement + if ($action == 'setmode' && $user->rights->societe->creer) + { + $object->fetch($id); + $result=$object->setPaymentMethods(GETPOST('mode_reglement_id','int')); + if ($result < 0) dol_print_error($db,$object->error); + } -// assujetissement a la TVA -if ($action == 'setassujtva' && $user->rights->societe->creer) -{ - $object->fetch($id); - $object->tva_assuj=$_POST['assujtva_value']; - $result=$object->update($object->id); - if ($result < 0) dol_print_error($db,$object->error); -} + // assujetissement a la TVA + if ($action == 'setassujtva' && $user->rights->societe->creer) + { + $object->fetch($id); + $object->tva_assuj=$_POST['assujtva_value']; + $result=$object->update($object->id); + if ($result < 0) dol_print_error($db,$object->error); + } -// set prospect level -if ($action == 'setprospectlevel' && $user->rights->societe->creer) -{ - $object->fetch($id); - $object->fk_prospectlevel=GETPOST('prospect_level_id','alpha'); - $result=$object->set_prospect_level($user); - if ($result < 0) setEventMessage($object->error,'errors'); -} + // set prospect level + if ($action == 'setprospectlevel' && $user->rights->societe->creer) + { + $object->fetch($id); + $object->fk_prospectlevel=GETPOST('prospect_level_id','alpha'); + $result=$object->set_prospect_level($user); + if ($result < 0) setEventMessage($object->error,'errors'); + } -// update prospect level -if ($action == 'cstc') -{ - $object->fetch($id); - $object->stcomm_id=GETPOST('stcomm','int'); - $result=$object->set_commnucation_level($user); - if ($result < 0) setEventMessage($object->error,'errors'); -} + // update prospect level + if ($action == 'cstc') + { + $object->fetch($id); + $object->stcomm_id=GETPOST('stcomm','int'); + $result=$object->set_commnucation_level($user); + if ($result < 0) setEventMessage($object->error,'errors'); + } -// update outstandng limit -if ($action == 'setOutstandingBill') -{ - if (!$cancelbutton) + // update outstandng limit + if ($action == 'setOutstandingBill') { $object->fetch($id); $object->outstanding_limit=GETPOST('OutstandingBill'); diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index ca4c27bfdbc..509b26ae104 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -110,559 +110,560 @@ $parameters=array(); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -// Action clone object -if ($action == 'confirm_clone' && $confirm == 'yes') +if (empty($reshook)) { - if (empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) + // Action clone object + if ($action == 'confirm_clone' && $confirm == 'yes') { - setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); - } - else - { - $result=$object->createFromClone($object->id,$_REQUEST["clone_content"],$_REQUEST["clone_receivers"]); - if ($result > 0) + if (empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) { - header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); - exit; + setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); } else { - setEventMessage($object->error, 'errors'); - } - } - $action=''; -} - -// Action send emailing for everybody -if ($action == 'sendallconfirmed' && $confirm == 'yes') -{ - if (empty($conf->global->MAILING_LIMIT_SENDBYWEB)) - { - //TODO: What is this for? - // Pour des raisons de securite, on ne permet pas cette fonction via l'IHM, - // on affiche donc juste un message - setEventMessage($langs->trans("MailingNeedCommand"), 'warnings'); - setEventMessage('', 'warnings'); - setEventMessage($langs->trans("MailingNeedCommand2"), 'warnings'); - $action=''; - } - else if ($conf->global->MAILING_LIMIT_SENDBYWEB < 0) - { - setEventMessage($langs->trans("NotEnoughPermissions"), 'warnings'); - $action=''; - } - else - { - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - if ($object->statut == 0) - { - dol_print_error('','ErrorMailIsNotValidated'); - exit; - } - - $id = $object->id; - $subject = $object->sujet; - $message = $object->body; - $from = $object->email_from; - $replyto = $object->email_replyto; - $errorsto = $object->email_errorsto; - // Le message est-il en html - $msgishtml=-1; // Unknown by default - if (preg_match('/[\s\t]*/i',$message)) $msgishtml=1; - - // Warning, we must not use begin-commit transaction here - // because we want to save update for each mail sent. - - $nbok=0; $nbko=0; - - // On choisit les mails non deja envoyes pour ce mailing (statut=0) - // ou envoyes en erreur (statut=-1) - $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.source_url, mc.source_id, mc.source_type, mc.tag"; - $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc"; - $sql .= " WHERE mc.statut < 1 AND mc.fk_mailing = ".$object->id; - - dol_syslog("card.php: select targets", LOG_DEBUG); - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); // nb of possible recipients - - if ($num) + $result=$object->createFromClone($object->id,$_REQUEST["clone_content"],$_REQUEST["clone_receivers"]); + if ($result > 0) { - dol_syslog("comm/mailing/card.php: nb of targets = ".$num, LOG_DEBUG); + header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); + exit; + } + else + { + setEventMessage($object->error, 'errors'); + } + } + $action=''; + } - $now=dol_now(); + // Action send emailing for everybody + if ($action == 'sendallconfirmed' && $confirm == 'yes') + { + if (empty($conf->global->MAILING_LIMIT_SENDBYWEB)) + { + //TODO: What is this for? + // Pour des raisons de securite, on ne permet pas cette fonction via l'IHM, + // on affiche donc juste un message + setEventMessage($langs->trans("MailingNeedCommand"), 'warnings'); + setEventMessage('', 'warnings'); + setEventMessage($langs->trans("MailingNeedCommand2"), 'warnings'); + $action=''; + } + else if ($conf->global->MAILING_LIMIT_SENDBYWEB < 0) + { + setEventMessage($langs->trans("NotEnoughPermissions"), 'warnings'); + $action=''; + } + else + { + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - // Positionne date debut envoi - $sql="UPDATE ".MAIN_DB_PREFIX."mailing SET date_envoi=".$db->idate($now)." WHERE rowid=".$object->id; + if ($object->statut == 0) + { + dol_print_error('','ErrorMailIsNotValidated'); + exit; + } + + $id = $object->id; + $subject = $object->sujet; + $message = $object->body; + $from = $object->email_from; + $replyto = $object->email_replyto; + $errorsto = $object->email_errorsto; + // Le message est-il en html + $msgishtml=-1; // Unknown by default + if (preg_match('/[\s\t]*/i',$message)) $msgishtml=1; + + // Warning, we must not use begin-commit transaction here + // because we want to save update for each mail sent. + + $nbok=0; $nbko=0; + + // On choisit les mails non deja envoyes pour ce mailing (statut=0) + // ou envoyes en erreur (statut=-1) + $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.source_url, mc.source_id, mc.source_type, mc.tag"; + $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc"; + $sql .= " WHERE mc.statut < 1 AND mc.fk_mailing = ".$object->id; + + dol_syslog("card.php: select targets", LOG_DEBUG); + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); // nb of possible recipients + + if ($num) + { + dol_syslog("comm/mailing/card.php: nb of targets = ".$num, LOG_DEBUG); + + $now=dol_now(); + + // Positionne date debut envoi + $sql="UPDATE ".MAIN_DB_PREFIX."mailing SET date_envoi=".$db->idate($now)." WHERE rowid=".$object->id; + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + + // Loop on each email and send it + $i = 0; + + while ($i < $num && $i < $conf->global->MAILING_LIMIT_SENDBYWEB) + { + + $res=1; + + $obj = $db->fetch_object($resql); + + // sendto en RFC2822 + $sendto = str_replace(',',' ',dolGetFirstLastname($obj->firstname, $obj->lastname))." <".$obj->email.">"; + + // Make substitutions on topic and body. From (AA=YY;BB=CC;...) we keep YY, CC, ... + $other=explode(';',$obj->other); + $tmpfield=explode('=',$other[0],2); $other1=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + $tmpfield=explode('=',$other[1],2); $other2=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + $tmpfield=explode('=',$other[2],2); $other3=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + $tmpfield=explode('=',$other[3],2); $other4=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + // Array of possible substitutions (See also fie mailing-send.php that should manage same substitutions) + $substitutionarray=array( + '__ID__' => $obj->source_id, + '__EMAIL__' => $obj->email, + '__LASTNAME__' => $obj->lastname, + '__FIRSTNAME__' => $obj->firstname, + '__MAILTOEMAIL__' => ''.$obj->email.'', + '__OTHER1__' => $other1, + '__OTHER2__' => $other2, + '__OTHER3__' => $other3, + '__OTHER4__' => $other4, + '__OTHER5__' => $other5, + '__CHECK_READ__' => '', + '__UNSUBSCRIBE__' => ''.$langs->trans("MailUnsubcribe").'' + ); + if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_SECURITY_TOKEN)) + { + $substitutionarray['__SECUREKEYPAYPAL__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2); + if (empty($conf->global->PAYPAL_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2); + else $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2); + } + $substitutionisok=true; + complete_substitutions_array($substitutionarray, $langs); + $newsubject=make_substitutions($subject,$substitutionarray); + $newmessage=make_substitutions($message,$substitutionarray); + + $arr_file = array(); + $arr_mime = array(); + $arr_name = array(); + $arr_css = array(); + + $listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0); + if (count($listofpaths)) + { + foreach($listofpaths as $key => $val) + { + $arr_file[]=$listofpaths[$key]['fullname']; + $arr_mime[]=dol_mimetype($listofpaths[$key]['name']); + $arr_name[]=$listofpaths[$key]['name']; + } + } + + // Fabrication du mail + $mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css); + + if ($mail->error) + { + $res=0; + } + if (! $substitutionisok) + { + $mail->error='Some substitution failed'; + $res=0; + } + + // Send mail + if ($res) + { + $res=$mail->sendfile(); + } + + if ($res) + { + // Mail successful + $nbok++; + + dol_syslog("comm/mailing/card.php: ok for #".$i.($mail->error?' - '.$mail->error:''), LOG_DEBUG); + + $sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles"; + $sql.=" SET statut=1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid; + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + else + { + //if cheack read is use then update prospect contact status + if (strpos($message, '__CHECK_READ__') !== false) + { + //Update status communication of thirdparty prospect + $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT source_id FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid=".$obj->rowid.")"; + dol_syslog("card.php: set prospect thirdparty status", LOG_DEBUG); + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + + //Update status communication of contact prospect + $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."socpeople AS sc INNER JOIN ".MAIN_DB_PREFIX."mailing_cibles AS mc ON mc.rowid=".$obj->rowid." AND mc.source_type = 'contact' AND mc.source_id = sc.rowid)"; + dol_syslog("card.php: set prospect contact status", LOG_DEBUG); + + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + } + } + + + //test if CHECK READ change statut prospect contact + } + else + { + // Mail failed + $nbko++; + + dol_syslog("comm/mailing/card.php: error for #".$i.($mail->error?' - '.$mail->error:''), LOG_WARNING); + + $sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles"; + $sql.=" SET statut=-1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid; + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + } + + $i++; + } + } + else + { + setEventMessage($langs->transnoentitiesnoconv("NoMoreRecipientToSendTo")); + } + + // Loop finished, set global statut of mail + if ($nbko > 0) + { + $statut=2; // Status 'sent partially' (because at least one error) + if ($nbok > 0) setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); + else setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); + } + else + { + if ($nbok >= $num) + { + $statut=3; // Send to everybody + setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); + } + else + { + $statut=2; // Status 'sent partially' (because not send to everybody) + setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); + } + } + + $sql="UPDATE ".MAIN_DB_PREFIX."mailing SET statut=".$statut." WHERE rowid=".$object->id; + dol_syslog("comm/mailing/card.php: update global status", LOG_DEBUG); $resql2=$db->query($sql); if (! $resql2) { dol_print_error($db); } - - // Loop on each email and send it - $i = 0; - - while ($i < $num && $i < $conf->global->MAILING_LIMIT_SENDBYWEB) - { - - $res=1; - - $obj = $db->fetch_object($resql); - - // sendto en RFC2822 - $sendto = str_replace(',',' ',dolGetFirstLastname($obj->firstname, $obj->lastname))." <".$obj->email.">"; - - // Make substitutions on topic and body. From (AA=YY;BB=CC;...) we keep YY, CC, ... - $other=explode(';',$obj->other); - $tmpfield=explode('=',$other[0],2); $other1=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - $tmpfield=explode('=',$other[1],2); $other2=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - $tmpfield=explode('=',$other[2],2); $other3=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - $tmpfield=explode('=',$other[3],2); $other4=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - // Array of possible substitutions (See also fie mailing-send.php that should manage same substitutions) - $substitutionarray=array( - '__ID__' => $obj->source_id, - '__EMAIL__' => $obj->email, - '__LASTNAME__' => $obj->lastname, - '__FIRSTNAME__' => $obj->firstname, - '__MAILTOEMAIL__' => ''.$obj->email.'', - '__OTHER1__' => $other1, - '__OTHER2__' => $other2, - '__OTHER3__' => $other3, - '__OTHER4__' => $other4, - '__OTHER5__' => $other5, - '__CHECK_READ__' => '', - '__UNSUBSCRIBE__' => ''.$langs->trans("MailUnsubcribe").'' - ); - if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_SECURITY_TOKEN)) - { - $substitutionarray['__SECUREKEYPAYPAL__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2); - if (empty($conf->global->PAYPAL_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2); - } - $substitutionisok=true; - complete_substitutions_array($substitutionarray, $langs); - $newsubject=make_substitutions($subject,$substitutionarray); - $newmessage=make_substitutions($message,$substitutionarray); - - $arr_file = array(); - $arr_mime = array(); - $arr_name = array(); - $arr_css = array(); - - $listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0); - if (count($listofpaths)) - { - foreach($listofpaths as $key => $val) - { - $arr_file[]=$listofpaths[$key]['fullname']; - $arr_mime[]=dol_mimetype($listofpaths[$key]['name']); - $arr_name[]=$listofpaths[$key]['name']; - } - } - - // Fabrication du mail - $mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css); - - if ($mail->error) - { - $res=0; - } - if (! $substitutionisok) - { - $mail->error='Some substitution failed'; - $res=0; - } - - // Send mail - if ($res) - { - $res=$mail->sendfile(); - } - - if ($res) - { - // Mail successful - $nbok++; - - dol_syslog("comm/mailing/card.php: ok for #".$i.($mail->error?' - '.$mail->error:''), LOG_DEBUG); - - $sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles"; - $sql.=" SET statut=1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid; - $resql2=$db->query($sql); - if (! $resql2) - { - dol_print_error($db); - } - else - { - //if cheack read is use then update prospect contact status - if (strpos($message, '__CHECK_READ__') !== false) - { - //Update status communication of thirdparty prospect - $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT source_id FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid=".$obj->rowid.")"; - dol_syslog("card.php: set prospect thirdparty status", LOG_DEBUG); - $resql2=$db->query($sql); - if (! $resql2) - { - dol_print_error($db); - } - - //Update status communication of contact prospect - $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."socpeople AS sc INNER JOIN ".MAIN_DB_PREFIX."mailing_cibles AS mc ON mc.rowid=".$obj->rowid." AND mc.source_type = 'contact' AND mc.source_id = sc.rowid)"; - dol_syslog("card.php: set prospect contact status", LOG_DEBUG); - - $resql2=$db->query($sql); - if (! $resql2) - { - dol_print_error($db); - } - } - } - - - //test if CHECK READ change statut prospect contact - } - else - { - // Mail failed - $nbko++; - - dol_syslog("comm/mailing/card.php: error for #".$i.($mail->error?' - '.$mail->error:''), LOG_WARNING); - - $sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles"; - $sql.=" SET statut=-1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid; - $resql2=$db->query($sql); - if (! $resql2) - { - dol_print_error($db); - } - } - - $i++; - } } else { - setEventMessage($langs->transnoentitiesnoconv("NoMoreRecipientToSendTo")); - } - - // Loop finished, set global statut of mail - if ($nbko > 0) - { - $statut=2; // Status 'sent partially' (because at least one error) - if ($nbok > 0) setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); - else setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); - } - else - { - if ($nbok >= $num) - { - $statut=3; // Send to everybody - setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); - } - else - { - $statut=2; // Status 'sent partially' (because not send to everybody) - setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); - } - } - - $sql="UPDATE ".MAIN_DB_PREFIX."mailing SET statut=".$statut." WHERE rowid=".$object->id; - dol_syslog("comm/mailing/card.php: update global status", LOG_DEBUG); - $resql2=$db->query($sql); - if (! $resql2) - { + dol_syslog($db->error()); dol_print_error($db); } + + $action = ''; } - else - { - dol_syslog($db->error()); - dol_print_error($db); - } - - $action = ''; - } -} - -// Action send test emailing -if ($action == 'send' && empty($_POST["cancel"])) -{ - $error=0; - - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - $object->sendto = $_POST["sendto"]; - if (! $object->sendto) - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("MailTo")), 'errors'); - $error++; } - if (! $error) + // Action send test emailing + if ($action == 'send' && empty($_POST["cancel"])) { - // Le message est-il en html - $msgishtml=-1; // Inconnu par defaut - if (preg_match('/[\s\t]*/i',$object->body)) $msgishtml=1; + $error=0; - // Pratique les substitutions sur le sujet et message - $tmpsujet=make_substitutions($object->sujet,$object->substitutionarrayfortest); - $tmpbody=make_substitutions($object->body,$object->substitutionarrayfortest); + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - $arr_file = array(); - $arr_mime = array(); - $arr_name = array(); - $arr_css = array(); - - // Ajout CSS - if (!empty($object->bgcolor)) $arr_css['bgcolor'] = (preg_match('/^#/',$object->bgcolor)?'':'#').$object->bgcolor; - if (!empty($object->bgimage)) $arr_css['bgimage'] = $object->bgimage; - - // Attached files - $listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0); - if (count($listofpaths)) + $object->sendto = $_POST["sendto"]; + if (! $object->sendto) { - foreach($listofpaths as $key => $val) + setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("MailTo")), 'errors'); + $error++; + } + + if (! $error) + { + // Le message est-il en html + $msgishtml=-1; // Inconnu par defaut + if (preg_match('/[\s\t]*/i',$object->body)) $msgishtml=1; + + // Pratique les substitutions sur le sujet et message + $tmpsujet=make_substitutions($object->sujet,$object->substitutionarrayfortest); + $tmpbody=make_substitutions($object->body,$object->substitutionarrayfortest); + + $arr_file = array(); + $arr_mime = array(); + $arr_name = array(); + $arr_css = array(); + + // Ajout CSS + if (!empty($object->bgcolor)) $arr_css['bgcolor'] = (preg_match('/^#/',$object->bgcolor)?'':'#').$object->bgcolor; + if (!empty($object->bgimage)) $arr_css['bgimage'] = $object->bgimage; + + // Attached files + $listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0); + if (count($listofpaths)) { - $arr_file[]=$listofpaths[$key]['fullname']; - $arr_mime[]=dol_mimetype($listofpaths[$key]['name']); - $arr_name[]=$listofpaths[$key]['name']; + foreach($listofpaths as $key => $val) + { + $arr_file[]=$listofpaths[$key]['fullname']; + $arr_mime[]=dol_mimetype($listofpaths[$key]['name']); + $arr_name[]=$listofpaths[$key]['name']; + } } + + $mailfile = new CMailFile($tmpsujet,$object->sendto,$object->email_from,$tmpbody, $arr_file,$arr_mime,$arr_name,'', '', 0, $msgishtml,$object->email_errorsto,$arr_css); + + $result=$mailfile->sendfile(); + if ($result) + { + setEventMessage($langs->trans("MailSuccessfulySent",$mailfile->getValidAddress($object->email_from,2),$mailfile->getValidAddress($object->sendto,2))); + } + else + { + setEventMessage($langs->trans("ResultKo").'
'.$mailfile->error.' '.$result, 'errors'); + } + + $action=''; } - - $mailfile = new CMailFile($tmpsujet,$object->sendto,$object->email_from,$tmpbody, $arr_file,$arr_mime,$arr_name,'', '', 0, $msgishtml,$object->email_errorsto,$arr_css); - - $result=$mailfile->sendfile(); - if ($result) - { - setEventMessage($langs->trans("MailSuccessfulySent",$mailfile->getValidAddress($object->email_from,2),$mailfile->getValidAddress($object->sendto,2))); - } - else - { - setEventMessage($langs->trans("ResultKo").'
'.$mailfile->error.' '.$result, 'errors'); - } - - $action=''; - } -} - -// Action add emailing -if ($action == 'add') -{ - $mesgs = array(); - - $object->email_from = trim($_POST["from"]); - $object->email_replyto = trim($_POST["replyto"]); - $object->email_errorsto = trim($_POST["errorsto"]); - $object->titre = trim($_POST["titre"]); - $object->sujet = trim($_POST["sujet"]); - $object->body = trim($_POST["body"]); - $object->bgcolor = trim($_POST["bgcolor"]); - $object->bgimage = trim($_POST["bgimage"]); - - if (! $object->titre) { - $mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle")); - } - if (! $object->sujet) { - $mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic")); - } - if (! $object->body) { - $mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage")); } - if (!count($mesgs)) - { - if ($object->create($user) >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - $mesgs[] = $object->error; - } - - setEventMessage($mesgs, 'errors'); - $action="create"; -} - -// Action update description of emailing -if ($action == 'settitre' || $action == 'setemail_from' || $action == 'setreplyto' || $action == 'setemail_errorsto') -{ - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - if ($action == 'settitre') $object->titre = trim(GETPOST('titre','alpha')); - else if ($action == 'setemail_from') $object->email_from = trim(GETPOST('email_from','alpha')); - else if ($action == 'setemail_replyto') $object->email_replyto = trim(GETPOST('email_replyto','alpha')); - else if ($action == 'setemail_errorsto') $object->email_errorsto = trim(GETPOST('email_errorsto','alpha')); - else if ($action == 'settitre' && empty($object->titre)) { - $mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle")); - } - else if ($action == 'setfrom' && empty($object->email_from)) { - $mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailFrom")); - } - - if (! $mesg) - { - if ($object->update($user) >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - $mesg = $object->error; - } - - setEventMessage($mesg, 'errors'); - $action=""; -} - -/* - * Add file in email form - */ -if (! empty($_POST['addfile'])) -{ - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - // Set tmp user directory - dol_add_file_process($upload_dir,0,0); - - $action="edit"; -} - -// Action remove file -if (! empty($_POST["removedfile"])) -{ - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - dol_remove_file_process($_POST['removedfile'],0); - - $action="edit"; -} - -// Action update emailing -if ($action == 'update' && empty($_POST["removedfile"]) && empty($_POST["cancel"])) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $isupload=0; - - if (! $isupload) + // Action add emailing + if ($action == 'add') { $mesgs = array(); + $object->email_from = trim($_POST["from"]); + $object->email_replyto = trim($_POST["replyto"]); + $object->email_errorsto = trim($_POST["errorsto"]); + $object->titre = trim($_POST["titre"]); $object->sujet = trim($_POST["sujet"]); $object->body = trim($_POST["body"]); $object->bgcolor = trim($_POST["bgcolor"]); $object->bgimage = trim($_POST["bgimage"]); + if (! $object->titre) { + $mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle")); + } if (! $object->sujet) { $mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic")); } - if (! $object->body) { + if (! $object->body) { $mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage")); } if (!count($mesgs)) + { + if ($object->create($user) >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + $mesgs[] = $object->error; + } + + setEventMessage($mesgs, 'errors'); + $action="create"; + } + + // Action update description of emailing + if ($action == 'settitre' || $action == 'setemail_from' || $action == 'setreplyto' || $action == 'setemail_errorsto') + { + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); + + if ($action == 'settitre') $object->titre = trim(GETPOST('titre','alpha')); + else if ($action == 'setemail_from') $object->email_from = trim(GETPOST('email_from','alpha')); + else if ($action == 'setemail_replyto') $object->email_replyto = trim(GETPOST('email_replyto','alpha')); + else if ($action == 'setemail_errorsto') $object->email_errorsto = trim(GETPOST('email_errorsto','alpha')); + else if ($action == 'settitre' && empty($object->titre)) { + $mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle")); + } + else if ($action == 'setfrom' && empty($object->email_from)) { + $mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailFrom")); + } + + if (! $mesg) { if ($object->update($user) >= 0) { header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); exit; } - $mesgs[] =$object->error; + $mesg = $object->error; } - setEventMessage($mesgs, 'errors'); + setEventMessage($mesg, 'errors'); + $action=""; + } + + /* + * Add file in email form + */ + if (! empty($_POST['addfile'])) + { + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + // Set tmp user directory + dol_add_file_process($upload_dir,0,0); + $action="edit"; } - else + + // Action remove file + if (! empty($_POST["removedfile"])) { + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + dol_remove_file_process($_POST['removedfile'],0); + $action="edit"; } -} -// Action confirmation validation -if ($action == 'confirm_valid' && $confirm == 'yes') -{ - if ($object->id > 0) + // Action update emailing + if ($action == 'update' && empty($_POST["removedfile"]) && empty($_POST["cancel"])) { - $object->valid($user); - setEventMessage($langs->trans("MailingSuccessfullyValidated")); - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else - { - dol_print_error($db); - } -} + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; -// Resend -if ($action == 'confirm_reset' && $confirm == 'yes') -{ - if ($object->id > 0) - { - $db->begin(); + $isupload=0; - $result=$object->valid($user); - if ($result > 0) + if (! $isupload) { - $result=$object->reset_targets_status($user); + $mesgs = array(); + + $object->sujet = trim($_POST["sujet"]); + $object->body = trim($_POST["body"]); + $object->bgcolor = trim($_POST["bgcolor"]); + $object->bgimage = trim($_POST["bgimage"]); + + if (! $object->sujet) { + $mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic")); + } + if (! $object->body) { + $mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage")); + } + + if (!count($mesgs)) + { + if ($object->update($user) >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + $mesgs[] =$object->error; + } + + setEventMessage($mesgs, 'errors'); + $action="edit"; } - - if ($result > 0) + else { - $db->commit(); + $action="edit"; + } + } + + // Action confirmation validation + if ($action == 'confirm_valid' && $confirm == 'yes') + { + if ($object->id > 0) + { + $object->valid($user); + setEventMessage($langs->trans("MailingSuccessfullyValidated")); header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); exit; } else { - setEventMessage($object->error, 'errors'); - $db->rollback(); + dol_print_error($db); } } - else + + // Resend + if ($action == 'confirm_reset' && $confirm == 'yes') { - dol_print_error($db); + if ($object->id > 0) + { + $db->begin(); + + $result=$object->valid($user); + if ($result > 0) + { + $result=$object->reset_targets_status($user); + } + + if ($result > 0) + { + $db->commit(); + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + setEventMessage($object->error, 'errors'); + $db->rollback(); + } + } + else + { + dol_print_error($db); + } + } + + // Action confirmation suppression + if ($action == 'confirm_delete' && $confirm == 'yes') + { + if ($object->delete($object->id)) + { + $url= (! empty($urlfrom) ? $urlfrom : 'list.php'); + header("Location: ".$url); + exit; + } + } + + if (! empty($_POST["cancel"])) + { + $action = ''; } } -// Action confirmation suppression -if ($action == 'confirm_delete' && $confirm == 'yes') -{ - if ($object->delete($object->id)) - { - $url= (! empty($urlfrom) ? $urlfrom : 'list.php'); - header("Location: ".$url); - exit; - } -} - -if (! empty($_POST["cancel"])) -{ - $action = ''; -} - - /* * View */ +$form = new Form($db); +$htmlother = new FormOther($db); $help_url='EN:Module_EMailing|FR:Module_Mailing|ES:Módulo_Mailing'; llxHeader('',$langs->trans("Mailing"),$help_url); -$form = new Form($db); -$htmlother = new FormOther($db); - if ($action == 'create') { // EMailing in creation mode diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index 7ef2f3bd4c9..50b3306e3f2 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -26,9 +26,9 @@ */ /** - * \file htdocs/comm/propal.php - * \ingroup propale - * \brief Page of commercial proposals card and list + * \file htdocs/comm/propal.php + * \ingroup propale + * \brief Page of commercial proposals card and list */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; @@ -108,681 +108,837 @@ $parameters = array('socid' => $socid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once - -// Action clone object -if ($action == 'confirm_clone' && $confirm == 'yes') +if (empty($reshook)) { - if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) + include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + // Action clone object + if ($action == 'confirm_clone' && $confirm == 'yes') { - setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); - } - else - { - if ($object->id > 0) { - $result = $object->createFromClone($socid); - if ($result > 0) { - header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result); - exit(); - } else { - setEventMessage($object->error, 'errors'); - $action = ''; + if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) + { + setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); + } + else + { + if ($object->id > 0) { + $result = $object->createFromClone($socid); + if ($result > 0) { + header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result); + exit(); + } else { + setEventMessage($object->error, 'errors'); + $action = ''; + } } } } -} -// Delete proposal -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->propal->supprimer) -{ - $result = $object->delete($user); - if ($result > 0) { - header('Location: ' . DOL_URL_ROOT . '/comm/propal/list.php'); - exit(); - } else { - $langs->load("errors"); - setEventMessage($langs->trans($object->error), 'errors'); - } -} - -// Remove line -else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->propal->creer) -{ - $result = $object->deleteline($lineid); - // reorder lines - if ($result) - $object->line_order(true); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); - exit(); -} - -// Validation -else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider) -{ - $result = $object->valid($user); - if ($result >= 0) + // Delete proposal + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->propal->supprimer) { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + $result = $object->delete($user); + if ($result > 0) { + header('Location: ' . DOL_URL_ROOT . '/comm/propal/list.php'); + exit(); + } else { + $langs->load("errors"); + setEventMessage($langs->trans($object->error), 'errors'); + } + } + + // Remove line + else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->propal->creer) + { + $result = $object->deleteline($lineid); + // reorder lines + if ($result) + $object->line_order(true); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit(); + } + + // Validation + else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider) + { + $result = $object->valid($user); + if ($result >= 0) { - // Define output language if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records - - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); } + } else { + $langs->load("errors"); + if (count($object->errors) > 0) setEventMessage($object->errors, 'errors'); + else setEventMessage($langs->trans($object->error), 'errors'); } - } else { - $langs->load("errors"); - if (count($object->errors) > 0) setEventMessage($object->errors, 'errors'); - else setEventMessage($langs->trans($object->error), 'errors'); - } -} - -else if ($action == 'setdate' && $user->rights->propal->creer) -{ - $datep = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - - if (empty($datep)) { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors'); } - if (! $error) { - $result = $object->set_date($user, $datep); + else if ($action == 'setdate' && $user->rights->propal->creer) + { + $datep = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + + if (empty($datep)) { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors'); + } + + if (! $error) { + $result = $object->set_date($user, $datep); + if ($result < 0) + dol_print_error($db, $object->error); + } + } + else if ($action == 'setecheance' && $user->rights->propal->creer) + { + $result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear'])); if ($result < 0) dol_print_error($db, $object->error); } -} -else if ($action == 'setecheance' && $user->rights->propal->creer) -{ - $result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear'])); - if ($result < 0) - dol_print_error($db, $object->error); -} -else if ($action == 'setdate_livraison' && $user->rights->propal->creer) -{ - $result = $object->set_date_livraison($user, dol_mktime(12, 0, 0, $_POST['liv_month'], $_POST['liv_day'], $_POST['liv_year'])); - if ($result < 0) - dol_print_error($db, $object->error); -} - -// Positionne ref client -else if ($action == 'set_ref_client' && $user->rights->propal->creer) -{ - $object->set_ref_client($user, $_POST['ref_client']); -} - -// Create proposal -else if ($action == 'add' && $user->rights->propal->creer) -{ - $object->socid = $socid; - $object->fetch_thirdparty(); - - $datep = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - $date_delivery = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); - $duration = GETPOST('duree_validite'); - - if (empty($datep)) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors'); - $action = 'create'; - $error ++; - } - if (empty($duration)) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ValidityDuration")), 'errors'); - $action = 'create'; - $error ++; - } - - if ($socid < 1) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); - $action = 'create'; - $error ++; - } - - if (! $error) + else if ($action == 'setdate_livraison' && $user->rights->propal->creer) { - $db->begin(); + $result = $object->set_date_livraison($user, dol_mktime(12, 0, 0, $_POST['liv_month'], $_POST['liv_day'], $_POST['liv_year'])); + if ($result < 0) + dol_print_error($db, $object->error); + } - // Si on a selectionne une propal a copier, on realise la copie - if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal')) + // Positionne ref client + else if ($action == 'set_ref_client' && $user->rights->propal->creer) + { + $object->set_ref_client($user, $_POST['ref_client']); + } + + // Create proposal + else if ($action == 'add' && $user->rights->propal->creer) + { + $object->socid = $socid; + $object->fetch_thirdparty(); + + $datep = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $date_delivery = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + $duration = GETPOST('duree_validite'); + + if (empty($datep)) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors'); + $action = 'create'; + $error ++; + } + if (empty($duration)) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ValidityDuration")), 'errors'); + $action = 'create'; + $error ++; + } + + if ($socid < 1) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); + $action = 'create'; + $error ++; + } + + if (! $error) { - if ($object->fetch(GETPOST('copie_propal')) > 0) { + $db->begin(); + + // Si on a selectionne une propal a copier, on realise la copie + if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal')) + { + if ($object->fetch(GETPOST('copie_propal')) > 0) { + $object->ref = GETPOST('ref'); + $object->datep = $datep; + $object->date_livraison = $date_delivery; + $object->availability_id = GETPOST('availability_id'); + $object->demand_reason_id = GETPOST('demand_reason_id'); + $object->fk_delivery_address = GETPOST('fk_address'); + $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); + $object->duree_validite = $duration; + $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->fk_account = GETPOST('fk_account', 'int'); + $object->remise_percent = GETPOST('remise_percent'); + $object->remise_absolue = GETPOST('remise_absolue'); + $object->socid = GETPOST('socid'); + $object->contactid = GETPOST('contactid'); + $object->fk_project = GETPOST('projectid'); + $object->modelpdf = GETPOST('model'); + $object->author = $user->id; // deprecated + $object->note = GETPOST('note'); + $object->statut = 0; + + $id = $object->create_from($user); + } else { + setEventMessage($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_propal')), 'errors'); + } + } else { $object->ref = GETPOST('ref'); + $object->ref_client = GETPOST('ref_client'); $object->datep = $datep; $object->date_livraison = $date_delivery; $object->availability_id = GETPOST('availability_id'); $object->demand_reason_id = GETPOST('demand_reason_id'); $object->fk_delivery_address = GETPOST('fk_address'); - $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); - $object->duree_validite = $duration; + $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); + $object->duree_validite = GETPOST('duree_validite'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->fk_account = GETPOST('fk_account', 'int'); - $object->remise_percent = GETPOST('remise_percent'); - $object->remise_absolue = GETPOST('remise_absolue'); - $object->socid = GETPOST('socid'); + $object->fk_account = GETPOST('fk_account', 'int'); $object->contactid = GETPOST('contactid'); $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated $object->note = GETPOST('note'); - $object->statut = 0; - $id = $object->create_from($user); - } else { - setEventMessage($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_propal')), 'errors'); - } - } else { - $object->ref = GETPOST('ref'); - $object->ref_client = GETPOST('ref_client'); - $object->datep = $datep; - $object->date_livraison = $date_delivery; - $object->availability_id = GETPOST('availability_id'); - $object->demand_reason_id = GETPOST('demand_reason_id'); - $object->fk_delivery_address = GETPOST('fk_address'); - $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); - $object->duree_validite = GETPOST('duree_validite'); - $object->cond_reglement_id = GETPOST('cond_reglement_id'); - $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->fk_account = GETPOST('fk_account', 'int'); - $object->contactid = GETPOST('contactid'); - $object->fk_project = GETPOST('projectid'); - $object->modelpdf = GETPOST('model'); - $object->author = $user->id; // deprecated - $object->note = GETPOST('note'); + $object->origin = GETPOST('origin'); + $object->origin_id = GETPOST('originid'); - $object->origin = GETPOST('origin'); - $object->origin_id = GETPOST('originid'); - - for($i = 1; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i ++) - { - if ($_POST['idprod' . $i]) { - $xid = 'idprod' . $i; - $xqty = 'qty' . $i; - $xremise = 'remise' . $i; - $object->add_product($_POST[$xid], $_POST[$xqty], $_POST[$xremise]); - } - } - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) { - $error ++; - $action = 'create'; - } - } - - if (! $error) - { - if ($origin && $originid) - { - // Parse element/subelement (ex: project_task) - $element = $subelement = $origin; - if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { - $element = $regs [1]; - $subelement = $regs [2]; - } - - // For compatibility - if ($element == 'order') { - $element = $subelement = 'commande'; - } - if ($element == 'propal') { - $element = 'comm/propal'; - $subelement = 'propal'; - } - if ($element == 'contract') { - $element = $subelement = 'contrat'; - } - if ($element == 'inter') { - $element = $subelement = 'ficheinter'; - } - if ($element == 'shipping') { - $element = $subelement = 'expedition'; - } - - $object->origin = $origin; - $object->origin_id = $originid; - - // Possibility to add external linked objects with hooks - $object->linked_objects [$object->origin] = $object->origin_id; - if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); - } - - $id = $object->create($user); - if ($id > 0) + for($i = 1; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i ++) { - dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); - - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); - $result = $srcobject->fetch($object->origin_id); - - if ($result > 0) - { - $lines = $srcobject->lines; - if (empty($lines) && method_exists($srcobject, 'fetch_lines')) - { - $srcobject->fetch_lines(); - $lines = $srcobject->lines; - } - - $fk_parent_line=0; - $num=count($lines); - for ($i=0;$i<$num;$i++) - { - $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); - $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); - - // Positive line - $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0); - - // Date start - $date_start = false; - if ($lines[$i]->date_debut_prevue) - $date_start = $lines[$i]->date_debut_prevue; - if ($lines[$i]->date_debut_reel) - $date_start = $lines[$i]->date_debut_reel; - if ($lines[$i]->date_start) - $date_start = $lines[$i]->date_start; - - // Date end - $date_end = false; - if ($lines[$i]->date_fin_prevue) - $date_end = $lines[$i]->date_fin_prevue; - if ($lines[$i]->date_fin_reel) - $date_end = $lines[$i]->date_fin_reel; - if ($lines[$i]->date_end) - $date_end = $lines[$i]->date_end; - - // Reset fk_parent_line for no child products and special product - if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { - $fk_parent_line = 0; - } - - // Extrafields - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) { - $lines[$i]->fetch_optionals($lines[$i]->rowid); - $array_option = $lines[$i]->array_options; - } - - $tva_tx=get_default_tva($mysoc, $object->thirdparty); - - $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $date_start, $date_end, $array_option); - - if ($result > 0) { - $lineid = $result; - } else { - $lineid = 0; - $error ++; - break; - } - - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { - $fk_parent_line = $result; - } - } - - // Hooks - $parameters = array('objFrom' => $srcobject); - $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook - if ($reshook < 0) - $error ++; - } else { - setEventMessages($srcobject->error, $srcobject->errors, 'errors'); - $error ++; - } - } else { - setEventMessages($object->error, $object->errors, 'errors'); - $error ++; - } - } // Standard creation - else - { - $id = $object->create($user); - } - - if ($id > 0) - { - // Insertion contact par defaut si defini - if (GETPOST('contactid') > 0) - { - $result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external'); - if ($result < 0) - { - $error++; - setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors'); + if ($_POST['idprod' . $i]) { + $xid = 'idprod' . $i; + $xqty = 'qty' . $i; + $xremise = 'remise' . $i; + $object->add_product($_POST[$xid], $_POST[$xqty], $_POST[$xremise]); } } - if (! $error) + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) { + $error ++; + $action = 'create'; + } + } + + if (! $error) + { + if ($origin && $originid) { - $db->commit(); + // Parse element/subelement (ex: project_task) + $element = $subelement = $origin; + if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { + $element = $regs [1]; + $subelement = $regs [2]; + } - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; + // For compatibility + if ($element == 'order') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; + $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + if ($element == 'inter') { + $element = $subelement = 'ficheinter'; + } + if ($element == 'shipping') { + $element = $subelement = 'expedition'; + } - $ret = $object->fetch($id); // Reload to get new records - $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result < 0) dol_print_error($db,$result); - } + $object->origin = $origin; + $object->origin_id = $originid; - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); - exit(); + // Possibility to add external linked objects with hooks + $object->linked_objects [$object->origin] = $object->origin_id; + if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) { + $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + } + + $id = $object->create($user); + if ($id > 0) + { + dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); + $result = $srcobject->fetch($object->origin_id); + + if ($result > 0) + { + $lines = $srcobject->lines; + if (empty($lines) && method_exists($srcobject, 'fetch_lines')) + { + $srcobject->fetch_lines(); + $lines = $srcobject->lines; + } + + $fk_parent_line=0; + $num=count($lines); + for ($i=0;$i<$num;$i++) + { + $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); + $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); + + // Positive line + $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0); + + // Date start + $date_start = false; + if ($lines[$i]->date_debut_prevue) + $date_start = $lines[$i]->date_debut_prevue; + if ($lines[$i]->date_debut_reel) + $date_start = $lines[$i]->date_debut_reel; + if ($lines[$i]->date_start) + $date_start = $lines[$i]->date_start; + + // Date end + $date_end = false; + if ($lines[$i]->date_fin_prevue) + $date_end = $lines[$i]->date_fin_prevue; + if ($lines[$i]->date_fin_reel) + $date_end = $lines[$i]->date_fin_reel; + if ($lines[$i]->date_end) + $date_end = $lines[$i]->date_end; + + // Reset fk_parent_line for no child products and special product + if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { + $fk_parent_line = 0; + } + + // Extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) { + $lines[$i]->fetch_optionals($lines[$i]->rowid); + $array_option = $lines[$i]->array_options; + } + + $tva_tx=get_default_tva($mysoc, $object->thirdparty); + + $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $date_start, $date_end, $array_option); + + if ($result > 0) { + $lineid = $result; + } else { + $lineid = 0; + $error ++; + break; + } + + // Defined the new fk_parent_line + if ($result > 0 && $lines[$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + + // Hooks + $parameters = array('objFrom' => $srcobject); + $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if ($reshook < 0) + $error ++; + } else { + setEventMessages($srcobject->error, $srcobject->errors, 'errors'); + $error ++; + } + } else { + setEventMessages($object->error, $object->errors, 'errors'); + $error ++; + } + } // Standard creation + else + { + $id = $object->create($user); + } + + if ($id > 0) + { + // Insertion contact par defaut si defini + if (GETPOST('contactid') > 0) + { + $result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external'); + if ($result < 0) + { + $error++; + setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors'); + } + } + + if (! $error) + { + $db->commit(); + + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + + $ret = $object->fetch($id); // Reload to get new records + $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) dol_print_error($db,$result); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); + exit(); + } + else + { + $db->rollback(); + $action='create'; + } } else { + setEventMessages($object->error, $object->errors, 'errors'); $db->rollback(); $action='create'; } } - else - { - setEventMessages($object->error, $object->errors, 'errors'); - $db->rollback(); - $action='create'; + } + } + + // Classify billed + else if ($action == 'classifybilled' && $user->rights->propal->cloturer) { + $object->cloture($user, 4, ''); + } + + // Reopen proposal + else if ($action == 'confirm_reopen' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { + // prevent browser refresh from reopening proposal several times + if ($object->statut == 2 || $object->statut == 3 || $object->statut == 4) { + $object->reopen($user, 1); + } + } + + // Close proposal + else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { + if (! GETPOST('statut')) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), 'errors'); + $action = 'statut'; + } else { + // prevent browser refresh from closing proposal several times + if ($object->statut == 1) { + $object->cloture($user, GETPOST('statut'), GETPOST('note')); } } } -} -// Classify billed -else if ($action == 'classifybilled' && $user->rights->propal->cloturer) { - $object->cloture($user, 4, ''); -} - -// Reopen proposal -else if ($action == 'confirm_reopen' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { - // prevent browser refresh from reopening proposal several times - if ($object->statut == 2 || $object->statut == 3 || $object->statut == 4) { - $object->reopen($user, 1); + // Classify billed + else if ($action == 'classifybilled' && $user->rights->propal->cloturer) { + $object->cloture($user, 4, ''); } -} -// Close proposal -else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { - if (! GETPOST('statut')) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), 'errors'); - $action = 'statut'; - } else { - // prevent browser refresh from closing proposal several times - if ($object->statut == 1) { - $object->cloture($user, GETPOST('statut'), GETPOST('note')); + // Reopen proposal + else if ($action == 'confirm_reopen' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { + // prevent browser refresh from reopening proposal several times + if ($object->statut == 2 || $object->statut == 3 || $object->statut == 4) { + $object->reopen($user, 1); } } -} -include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; - - -/* - * Send mail - */ - -// Actions to send emails -$actiontypecode='AC_PROP'; -$trigger_name='PROPAL_SENTBYMAIL'; -$paramname='id'; -$mode='emailfromproposal'; -include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; - - - -// Go back to draft -if ($action == 'modif' && $user->rights->propal->creer) -{ - $object->set_draft($user); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } -} - -else if ($action == "setabsolutediscount" && $user->rights->propal->creer) { - if ($_POST["remise_id"]) { - if ($object->id > 0) { - $result = $object->insert_discount($_POST["remise_id"]); - if ($result < 0) { - setEventMessage($object->error, 'errors'); + // Close proposal + else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { + if (! GETPOST('statut')) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), 'errors'); + $action = 'statut'; + } else { + // prevent browser refresh from closing proposal several times + if ($object->statut == 1) { + $object->cloture($user, GETPOST('statut'), GETPOST('note')); } } } -} -// Add line -else if ($action == 'addline' && $user->rights->propal->creer) { + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; - // Set if we used free entry or predefined product - $predef=''; - $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); - $price_ht = GETPOST('price_ht'); - if (GETPOST('prod_entry_mode') == 'free') + + /* + * Send mail + */ + + // Actions to send emails + $actiontypecode='AC_PROP'; + $trigger_name='PROPAL_SENTBYMAIL'; + $paramname='id'; + $mode='emailfromproposal'; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + + + + // Go back to draft + if ($action == 'modif' && $user->rights->propal->creer) { - $idprod=0; - $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - } - else - { - $idprod=GETPOST('idprod', 'int'); - $tva_tx = ''; - } + $object->set_draft($user); - $qty = GETPOST('qty' . $predef); - $remise_percent = GETPOST('remise_percent' . $predef); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key]); + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); - $error ++; - } - - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && $price_ht == '') // Unit price can be 0 but not ''. Also price can be negative for proposal. - { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), 'errors'); - $error ++; - } - - if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { - $pu_ht = 0; - $pu_ttc = 0; - $price_min = 0; - $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT'); - - $db->begin(); - - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - if (! empty($idprod)) { - $prod = new Product($db); - $prod->fetch($idprod); - - $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); - - // If prices fields are update - $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id); - $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id); - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - - // On defini prix unitaire - if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->thirdparty->price_level) - { - $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; - $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; - $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; - $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; - if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level]; - if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level]; + else if ($action == "setabsolutediscount" && $user->rights->propal->creer) { + if ($_POST["remise_id"]) { + if ($object->id > 0) { + $result = $object->insert_discount($_POST["remise_id"]); + if ($result < 0) { + setEventMessage($object->error, 'errors'); } - elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) - { - require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + } + } + } - $prodcustprice = new Productcustomerprice($db); + // Add line + else if ($action == 'addline' && $user->rights->propal->creer) { - $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + // Set if we used free entry or predefined product + $predef=''; + $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); + $price_ht = GETPOST('price_ht'); + if (GETPOST('prod_entry_mode') == 'free') + { + $idprod=0; + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + } + else + { + $idprod=GETPOST('idprod', 'int'); + $tva_tx = ''; + } - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); - if ($result) { - if (count($prodcustprice->lines) > 0) { - $pu_ht = price($prodcustprice->lines [0]->price); - $pu_ttc = price($prodcustprice->lines [0]->price_ttc); - $price_base_type = $prodcustprice->lines [0]->price_base_type; - $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; + $qty = GETPOST('qty' . $predef); + $remise_percent = GETPOST('remise_percent' . $predef); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); + $error ++; + } + + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && $price_ht == '') // Unit price can be 0 but not ''. Also price can be negative for proposal. + { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), 'errors'); + $error ++; + } + + if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { + $pu_ht = 0; + $pu_ttc = 0; + $price_min = 0; + $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT'); + + $db->begin(); + + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + if (! empty($idprod)) { + $prod = new Product($db); + $prod->fetch($idprod); + + $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); + + // If prices fields are update + $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id); + $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id); + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + + // On defini prix unitaire + if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->thirdparty->price_level) + { + $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; + $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; + if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level]; + if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level]; + } + elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + + $prodcustprice = new Productcustomerprice($db); + + $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result) { + if (count($prodcustprice->lines) > 0) { + $pu_ht = price($prodcustprice->lines [0]->price); + $pu_ttc = price($prodcustprice->lines [0]->price_ttc); + $price_base_type = $prodcustprice->lines [0]->price_base_type; + $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; + } } } - } - // if price ht is forced (ie: calculated by margin rate and cost price) - if (! empty($price_ht)) { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } - - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - elseif ($tva_tx != $prod->tva_tx) { - if ($price_base_type != 'HT') { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); - } else { + // if price ht is forced (ie: calculated by margin rate and cost price) + if (! empty($price_ht)) { + $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); } - } - $desc = ''; - - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $outputlangs = $langs; - $newlang = ''; - if (empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if (empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + elseif ($tva_tx != $prod->tva_tx) { + if ($price_base_type != 'HT') { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); + } else { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } } - $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; + $desc = ''; + + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if (empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; + } else { + $desc = $prod->description; + } + + $desc = dol_concatdesc($desc, $product_desc); + + // Add custom code and origin country into description + if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { + $tmptxt = '('; + if (! empty($prod->customcode)) + $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; + if (! empty($prod->customcode) && ! empty($prod->country_code)) + $tmptxt .= ' - '; + if (! empty($prod->country_code)) + $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); + $tmptxt .= ')'; + $desc = dol_concatdesc($desc, $tmptxt); + } + + $type = $prod->type; + } else { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); + $tva_tx = str_replace('*', '', $tva_tx); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + $desc = $product_desc; + $type = GETPOST('type'); + } + + // Margin + $fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); + $buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); + + $date_start = dol_mktime(0, 0, 0, GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year')); + $date_end = dol_mktime(0, 0, 0, GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year')); + + // Local Taxes + $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty); + $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty); + + $info_bits = 0; + if ($tva_npr) + $info_bits |= 0x01; + + if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { + $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); + setEventMessage($mesg, 'errors'); + } else { + // Insert line + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_option); + + if ($result > 0) { + $db->commit(); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST['prod_entry_mode']); + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); + unset($_POST['np_marginRate']); + unset($_POST['np_markRate']); + unset($_POST['dp_desc']); + unset($_POST['idprod']); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); } else { - $desc = $prod->description; + $db->rollback(); + + setEventMessage($object->error, 'errors'); } - - $desc = dol_concatdesc($desc, $product_desc); - - // Add custom code and origin country into description - if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { - $tmptxt = '('; - if (! empty($prod->customcode)) - $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; - if (! empty($prod->customcode) && ! empty($prod->country_code)) - $tmptxt .= ' - '; - if (! empty($prod->country_code)) - $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); - $tmptxt .= ')'; - $desc = dol_concatdesc($desc, $tmptxt); - } - - $type = $prod->type; - } else { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); - $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); - $tva_tx = str_replace('*', '', $tva_tx); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - $desc = $product_desc; - $type = GETPOST('type'); + } } + } - // Margin - $fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); - $buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); - - $date_start = dol_mktime(0, 0, 0, GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year')); - $date_end = dol_mktime(0, 0, 0, GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year')); - - // Local Taxes - $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty); - $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty); - + // Mise a jour d'une ligne dans la propale + else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('save') == $langs->trans("Save")) { + // Define info_bits $info_bits = 0; - if ($tva_npr) + if (preg_match('/\*/', GETPOST('tva_tx'))) $info_bits |= 0x01; - if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { - $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); - setEventMessage($mesg, 'errors'); - } else { - // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_option); + // Clean parameters + $description = dol_htmlcleanlastbr(GETPOST('product_desc')); - if ($result > 0) { + // Define vat_rate + $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty); + $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty); + $pu_ht = GETPOST('price_ht'); + + // Add buying price + $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : ''); + $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : ''); + + $date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + // Define special_code for special lines + $special_code=GETPOST('special_code'); + if (! GETPOST('qty')) $special_code=3; + + // Check minimum price + $productid = GETPOST('productid', 'int'); + if (! empty($productid)) { + $product = new Product($db); + $res = $product->fetch($productid); + + $type = $product->type; + + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) + $price_min = $product->multiprices_min [$object->thirdparty->price_level]; + + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); + + if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { + setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); + $error ++; + } + } else { + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + + // Check parameters + if (GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); + $error ++; + } + } + + if (! $error) { + $db->begin(); + + $result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_option); + + if ($result >= 0) { $db->commit(); if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { @@ -797,10 +953,9 @@ else if ($action == 'addline' && $user->rights->propal->creer) { $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - unset($_POST['prod_entry_mode']); - unset($_POST['qty']); unset($_POST['type']); + unset($_POST['productid']); unset($_POST['remise_percent']); unset($_POST['price_ht']); unset($_POST['price_ttc']); @@ -810,23 +965,6 @@ else if ($action == 'addline' && $user->rights->propal->creer) { unset($_POST['product_desc']); unset($_POST['fournprice']); unset($_POST['buying_price']); - unset($_POST['np_marginRate']); - unset($_POST['np_markRate']); - unset($_POST['dp_desc']); - unset($_POST['idprod']); - - unset($_POST['date_starthour']); - unset($_POST['date_startmin']); - unset($_POST['date_startsec']); - unset($_POST['date_startday']); - unset($_POST['date_startmonth']); - unset($_POST['date_startyear']); - unset($_POST['date_endhour']); - unset($_POST['date_endmin']); - unset($_POST['date_endsec']); - unset($_POST['date_endday']); - unset($_POST['date_endmonth']); - unset($_POST['date_endyear']); } else { $db->rollback(); @@ -834,315 +972,206 @@ else if ($action == 'addline' && $user->rights->propal->creer) { } } } -} -// Mise a jour d'une ligne dans la propale -else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('save') == $langs->trans("Save")) { - // Define info_bits - $info_bits = 0; - if (preg_match('/\*/', GETPOST('tva_tx'))) - $info_bits |= 0x01; - - // Clean parameters - $description = dol_htmlcleanlastbr(GETPOST('product_desc')); - - // Define vat_rate - $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - $vat_rate = str_replace('*', '', $vat_rate); - $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty); - $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty); - $pu_ht = GETPOST('price_ht'); - - // Add buying price - $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : ''); - $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : ''); - - $date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key]); - } + else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('cancel') == $langs->trans('Cancel')) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition + exit(); } - // Define special_code for special lines - $special_code=GETPOST('special_code'); - if (! GETPOST('qty')) $special_code=3; - - // Check minimum price - $productid = GETPOST('productid', 'int'); - if (! empty($productid)) { - $product = new Product($db); - $res = $product->fetch($productid); - - $type = $product->type; - - $price_min = $product->price_min; - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) - $price_min = $product->multiprices_min [$object->thirdparty->price_level]; - - $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); - - if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); - $error ++; + // Generation doc (depuis lien ou depuis cartouche doc) + else if ($action == 'builddoc' && $user->rights->propal->creer) { + if (GETPOST('model')) { + $object->setDocModel($user, GETPOST('model')); } - } else { - $type = GETPOST('type'); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - // Check parameters - if (GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); - $error ++; + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); } - } + $ret = $object->fetch($id); // Reload to get new records + $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if (! $error) { - $db->begin(); - - $result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_option); - - if ($result >= 0) { - $db->commit(); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['productid']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); - unset($_POST['price_ttc']); - unset($_POST['tva_tx']); - unset($_POST['product_ref']); - unset($_POST['product_label']); - unset($_POST['product_desc']); - unset($_POST['fournprice']); - unset($_POST['buying_price']); + if ($result <= 0) { + dol_print_error($db, $result); + exit(); } else { - $db->rollback(); - - setEventMessage($object->error, 'errors'); + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#builddoc')); + exit(); } } -} -else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('cancel') == $langs->trans('Cancel')) { - header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition - exit(); -} - -// Generation doc (depuis lien ou depuis cartouche doc) -else if ($action == 'builddoc' && $user->rights->propal->creer) { - if (GETPOST('model')) { - $object->setDocModel($user, GETPOST('model')); - } - - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - - if ($result <= 0) { - dol_print_error($db, $result); - exit(); - } else { - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#builddoc')); - exit(); - } -} - -// Remove file in doc form -else if ($action == 'remove_file' && $user->rights->propal->creer) { - if ($object->id > 0) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - $langs->load("other"); - $upload_dir = $conf->propal->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) - setEventMessage($langs->trans("FileWasRemoved", GETPOST('file'))); - else - setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors'); - } -} - -// Set project -else if ($action == 'classin' && $user->rights->propal->creer) { - $object->setProject($_POST['projectid']); -} - -// Delai de livraison -else if ($action == 'setavailability' && $user->rights->propal->creer) { - $result = $object->availability($_POST['availability_id']); -} - -// Origine de la propale -else if ($action == 'setdemandreason' && $user->rights->propal->creer) { - $result = $object->demand_reason($_POST['demand_reason_id']); -} - -// Conditions de reglement -else if ($action == 'setconditions' && $user->rights->propal->creer) { - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); -} - -else if ($action == 'setremisepercent' && $user->rights->propal->creer) { - $result = $object->set_remise_percent($user, $_POST['remise_percent']); -} - -else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) { - $result = $object->set_remise_absolue($user, $_POST['remise_absolue']); -} - -// Mode de reglement -else if ($action == 'setmode' && $user->rights->propal->creer) { - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); -} - -// bank account -else if ($action == 'setbankaccount' && $user->rights->propal->creer) { - $result=$object->setBankAccount(GETPOST('fk_account', 'int')); -} - -// shipping method -else if ($action == 'setshippingmethod' && $user->rights->propal->creer) { - $result=$object->setShippingMethod(GETPOST('shipping_method_id', 'int')); -} - -/* - * Ordonnancement des lignes -*/ - -else if ($action == 'up' && $user->rights->propal->creer) { - $object->line_up(GETPOST('rowid')); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); - exit(); -} - -else if ($action == 'down' && $user->rights->propal->creer) { - $object->line_down(GETPOST('rowid')); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); - exit(); -} else if ($action == 'update_extras') { - // Fill array 'array_options' with data from update form - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); - if ($ret < 0) - $error ++; - - if (! $error) { - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('propaldao')); - $parameters = array('id' => $object->id); - $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been - // modified by - // some hooks - if (empty($reshook)) { - $result = $object->insertExtraFields(); - if ($result < 0) { - $error ++; - } - } else if ($reshook < 0) - $error ++; - } - - if ($error) - $action = 'edit_extras'; -} - -if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->creer) -{ - if ($action == 'addcontact') - { + // Remove file in doc form + else if ($action == 'remove_file' && $user->rights->propal->creer) { if ($object->id > 0) { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $langs->load("other"); + $upload_dir = $conf->propal->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret = dol_delete_file($file, 0, 0, 0, $object); + if ($ret) + setEventMessage($langs->trans("FileWasRemoved", GETPOST('file'))); + else + setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors'); + } + } + + // Set project + else if ($action == 'classin' && $user->rights->propal->creer) { + $object->setProject($_POST['projectid']); + } + + // Delai de livraison + else if ($action == 'setavailability' && $user->rights->propal->creer) { + $result = $object->availability($_POST['availability_id']); + } + + // Origine de la propale + else if ($action == 'setdemandreason' && $user->rights->propal->creer) { + $result = $object->demand_reason($_POST['demand_reason_id']); + } + + // Conditions de reglement + else if ($action == 'setconditions' && $user->rights->propal->creer) { + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + } + + else if ($action == 'setremisepercent' && $user->rights->propal->creer) { + $result = $object->set_remise_percent($user, $_POST['remise_percent']); + } + + else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) { + $result = $object->set_remise_absolue($user, $_POST['remise_absolue']); + } + + // Mode de reglement + else if ($action == 'setmode' && $user->rights->propal->creer) { + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); + } + + // bank account + else if ($action == 'setbankaccount' && $user->rights->propal->creer) { + $result=$object->setBankAccount(GETPOST('fk_account', 'int')); + } + + // shipping method + else if ($action == 'setshippingmethod' && $user->rights->propal->creer) { + $result=$object->setShippingMethod(GETPOST('shipping_method_id', 'int')); + } + + /* + * Ordonnancement des lignes + */ + + else if ($action == 'up' && $user->rights->propal->creer) { + $object->line_up(GETPOST('rowid')); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit(); - } else { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - $langs->load("errors"); - setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors'); + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); + exit(); + } + + else if ($action == 'down' && $user->rights->propal->creer) { + $object->line_down(GETPOST('rowid')); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); + exit(); + } else if ($action == 'update_extras') { + // Fill array 'array_options' with data from update form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) + $error ++; + + if (! $error) { + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('propaldao')); + $parameters = array('id' => $object->id); + $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been + // modified by + // some hooks + if (empty($reshook)) { + $result = $object->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } else if ($reshook < 0) + $error ++; + } + + if ($error) + $action = 'edit_extras'; + } + + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->creer) + { + if ($action == 'addcontact') + { + if ($object->id > 0) { + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); + } + + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); } else { - setEventMessage($object->error, 'errors'); + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors'); + } else { + setEventMessage($object->error, 'errors'); + } } } - } - // Bascule du statut d'un contact - else if ($action == 'swapstatut') { - if ($object->fetch($id) > 0) { - $result = $object->swapContactStatus(GETPOST('ligne')); - } else { - dol_print_error($db); + // Bascule du statut d'un contact + else if ($action == 'swapstatut') { + if ($object->fetch($id) > 0) { + $result = $object->swapContactStatus(GETPOST('ligne')); + } else { + dol_print_error($db); + } } - } - // Efface un contact - else if ($action == 'deletecontact') { - $object->fetch($id); - $result = $object->delete_contact($lineid); + // Efface un contact + else if ($action == 'deletecontact') { + $object->fetch($id); + $result = $object->delete_contact($lineid); - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit(); - } else { - dol_print_error($db); + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); + } else { + dol_print_error($db); + } } } } @@ -1239,7 +1268,7 @@ if ($action == 'create') } dol_fiche_head(); - + print ''; // Reference @@ -1512,7 +1541,7 @@ if ($action == 'create') if (! empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE) || ! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) print '
'; dol_fiche_end(); - + $langs->load("bills"); print '
'; print ''; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 724a3ebe45c..410b6f2dafb 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2550,21 +2550,18 @@ class Propal extends CommonObject { $mybool=false; - $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); - foreach ($dirmodels as $reldir) - { - $file = $conf->global->PROPALE_ADDON.".php"; - $classname = $conf->global->PROPALE_ADDON; + $file = $conf->global->PROPALE_ADDON.".php"; + $classname = $conf->global->PROPALE_ADDON; - // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot.$reldir."/core/modules/propale/"; - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } - } + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/propale/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } if (! $mybool) { @@ -2581,14 +2578,14 @@ class Propal extends CommonObject return $numref; } else - { + { $this->error=$obj->error; //dol_print_error($db,"Propale::getNextNumRef ".$obj->error); return ""; } } else - { + { $langs->load("errors"); print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete"); return ""; diff --git a/htdocs/comm/prospect/list.php b/htdocs/comm/prospect/list.php index dcebc06a43d..896168baa80 100644 --- a/htdocs/comm/prospect/list.php +++ b/htdocs/comm/prospect/list.php @@ -177,11 +177,13 @@ $parameters=array(); $reshook=$hookmanager->executeHooks('doActions',$parameters); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if ($action == 'cstc') -{ - $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm = ".$_GET["pstcomm"]; - $sql .= " WHERE rowid = ".$_GET["socid"]; - $result=$db->query($sql); +if (empty($reshook)) { + if ($action == 'cstc') + { + $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm = ".$_GET["pstcomm"]; + $sql .= " WHERE rowid = ".$_GET["socid"]; + $result=$db->query($sql); + } } diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index f20201ee5cc..2296e8bd0a0 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -102,44 +102,88 @@ $parameters = array('socid' => $socid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once - -// Action clone object -if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->commande->creer) +if (empty($reshook)) { - if (1==0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) - { - setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); - } - else - { - if ($object->id > 0) - { - // Because createFromClone modifies the object, we must clone it so that we can restore it later - $orig = dol_clone($object); + include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once - $result=$object->createFromClone($socid); + // Action clone object + if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->commande->creer) + { + if (1==0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) + { + setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); + } + else + { + if ($object->id > 0) + { + // Because createFromClone modifies the object, we must clone it so that we can restore it later + $orig = dol_clone($object); + + $result=$object->createFromClone($socid); + if ($result > 0) + { + header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); + exit; + } + else + { + setEventMessage($object->error, 'errors'); + $object = $orig; + $action=''; + } + } + } + } + + // Reopen a closed order + else if ($action == 'reopen' && $user->rights->commande->creer) { + if ($object->statut == 3) { + $result = $object->set_reopen($user); if ($result > 0) { - header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); exit; } else { setEventMessage($object->error, 'errors'); - $object = $orig; - $action=''; } } } -} -// Reopen a closed order -else if ($action == 'reopen' && $user->rights->commande->creer) { - if ($object->statut == 3) { - $result = $object->set_reopen($user); - if ($result > 0) - { + // Suppression de la commande + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->commande->supprimer) { + $result = $object->delete($user); + if ($result > 0) { + header('Location: index.php'); + exit; + } + else { + setEventMessage($object->error, 'errors'); + } + } + + // Remove a product line + else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->commande->creer) { + $result = $object->deleteline($lineid); + if ($result > 0) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $ret = $object->fetch($object->id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); exit; } @@ -148,705 +192,300 @@ else if ($action == 'reopen' && $user->rights->commande->creer) { setEventMessage($object->error, 'errors'); } } -} -// Suppression de la commande -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->commande->supprimer) { - $result = $object->delete($user); - if ($result > 0) { - header('Location: index.php'); - exit; + // Categorisation dans projet + else if ($action == 'classin' && $user->rights->commande->creer) { + $object->setProject(GETPOST('projectid')); } - else { - setEventMessage($object->error, 'errors'); - } -} -// Remove a product line -else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->commande->creer) { - $result = $object->deleteline($lineid); - if ($result > 0) { - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $ret = $object->fetch($object->id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + // Add order + else if ($action == 'add' && $user->rights->commande->creer) { + $datecommande = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $datelivraison = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + + if ($datecommande == '') { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')), 'errors'); + $action = 'create'; + $error ++; } - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; - } - else - { - setEventMessage($object->error, 'errors'); - } -} + if ($socid < 1) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); + $action = 'create'; + $error ++; + } -// Categorisation dans projet -else if ($action == 'classin' && $user->rights->commande->creer) { - $object->setProject(GETPOST('projectid')); -} + if (! $error) { + $object->socid = $socid; + $object->fetch_thirdparty(); -// Add order -else if ($action == 'add' && $user->rights->commande->creer) { - $datecommande = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - $datelivraison = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + $db->begin(); - if ($datecommande == '') { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')), 'errors'); - $action = 'create'; - $error ++; - } + $object->date_commande = $datecommande; + $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public'); + $object->source = GETPOST('source_id'); + $object->fk_project = GETPOST('projectid'); + $object->ref_client = GETPOST('ref_client'); + $object->modelpdf = GETPOST('model'); + $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->fk_account = GETPOST('fk_account', 'int'); + $object->availability_id = GETPOST('availability_id'); + $object->demand_reason_id = GETPOST('demand_reason_id'); + $object->date_livraison = $datelivraison; + $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); + $object->fk_delivery_address = GETPOST('fk_address'); + $object->contactid = GETPOST('contactid'); - if ($socid < 1) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); - $action = 'create'; - $error ++; - } + // If creation from another object of another module (Example: origin=propal, originid=1) + if (! empty($origin) && ! empty($originid)) { + // Parse element/subelement (ex: project_task) + $element = $subelement = $origin; + if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { + $element = $regs [1]; + $subelement = $regs [2]; + } - if (! $error) { - $object->socid = $socid; - $object->fetch_thirdparty(); + // For compatibility + if ($element == 'order') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; + $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } - $db->begin(); + $object->origin = $origin; + $object->origin_id = $originid; - $object->date_commande = $datecommande; - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); - $object->source = GETPOST('source_id'); - $object->fk_project = GETPOST('projectid'); - $object->ref_client = GETPOST('ref_client'); - $object->modelpdf = GETPOST('model'); - $object->cond_reglement_id = GETPOST('cond_reglement_id'); - $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->fk_account = GETPOST('fk_account', 'int'); - $object->availability_id = GETPOST('availability_id'); - $object->demand_reason_id = GETPOST('demand_reason_id'); - $object->date_livraison = $datelivraison; - $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); - $object->fk_delivery_address = GETPOST('fk_address'); - $object->contactid = GETPOST('contactid'); + // Possibility to add external linked objects with hooks + $object->linked_objects [$object->origin] = $object->origin_id; + $other_linked_objects = GETPOST('other_linked_objects', 'array'); + if (! empty($other_linked_objects)) { + $object->linked_objects = array_merge($object->linked_objects, $other_linked_objects); + } - // If creation from another object of another module (Example: origin=propal, originid=1) - if (! empty($origin) && ! empty($originid)) { - // Parse element/subelement (ex: project_task) - $element = $subelement = $origin; - if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { - $element = $regs [1]; - $subelement = $regs [2]; - } + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) + $error ++; - // For compatibility - if ($element == 'order') { - $element = $subelement = 'commande'; - } - if ($element == 'propal') { - $element = 'comm/propal'; - $subelement = 'propal'; - } - if ($element == 'contract') { - $element = $subelement = 'contrat'; - } - - $object->origin = $origin; - $object->origin_id = $originid; - - // Possibility to add external linked objects with hooks - $object->linked_objects [$object->origin] = $object->origin_id; - $other_linked_objects = GETPOST('other_linked_objects', 'array'); - if (! empty($other_linked_objects)) { - $object->linked_objects = array_merge($object->linked_objects, $other_linked_objects); - } - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) - $error ++; - - if (! $error) - { - $object_id = $object->create($user); - - if ($object_id > 0) + if (! $error) { - dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + $object_id = $object->create($user); - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); - $result = $srcobject->fetch($object->origin_id); - if ($result > 0) + if ($object_id > 0) { - $lines = $srcobject->lines; - if (empty($lines) && method_exists($srcobject, 'fetch_lines')) + dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); + $result = $srcobject->fetch($object->origin_id); + if ($result > 0) { - $srcobject->fetch_lines(); $lines = $srcobject->lines; - } - - $fk_parent_line = 0; - $num = count($lines); - - for($i = 0; $i < $num; $i ++) - { - $label = (! empty($lines [$i]->label) ? $lines [$i]->label : ''); - $desc = (! empty($lines [$i]->desc) ? $lines [$i]->desc : $lines [$i]->libelle); - $product_type = (! empty($lines [$i]->product_type) ? $lines [$i]->product_type : 0); - - // Dates - // TODO mutualiser - $date_start = $lines [$i]->date_debut_prevue; - if ($lines [$i]->date_debut_reel) - $date_start = $lines [$i]->date_debut_reel; - if ($lines [$i]->date_start) - $date_start = $lines [$i]->date_start; - $date_end = $lines [$i]->date_fin_prevue; - if ($lines [$i]->date_fin_reel) - $date_end = $lines [$i]->date_fin_reel; - if ($lines [$i]->date_end) - $date_end = $lines [$i]->date_end; - - // Reset fk_parent_line for no child products and special product - if (($lines [$i]->product_type != 9 && empty($lines [$i]->fk_parent_line)) || $lines [$i]->product_type == 9) { - $fk_parent_line = 0; - } - - // Extrafields - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) // For avoid conflicts if - // trigger used + if (empty($lines) && method_exists($srcobject, 'fetch_lines')) { - $lines [$i]->fetch_optionals($lines [$i]->rowid); - $array_option = $lines [$i]->array_options; + $srcobject->fetch_lines(); + $lines = $srcobject->lines; } - $result = $object->addline($desc, $lines [$i]->subprice, $lines [$i]->qty, $lines [$i]->tva_tx, $lines [$i]->localtax1_tx, $lines [$i]->localtax2_tx, $lines [$i]->fk_product, $lines [$i]->remise_percent, $lines [$i]->info_bits, $lines [$i]->fk_remise_except, 'HT', 0, $date_start, $date_end, $product_type, $lines [$i]->rang, $lines [$i]->special_code, $fk_parent_line, $lines [$i]->fk_fournprice, $lines [$i]->pa_ht, $label, $array_option); + $fk_parent_line = 0; + $num = count($lines); - if ($result < 0) { + for($i = 0; $i < $num; $i ++) + { + $label = (! empty($lines [$i]->label) ? $lines [$i]->label : ''); + $desc = (! empty($lines [$i]->desc) ? $lines [$i]->desc : $lines [$i]->libelle); + $product_type = (! empty($lines [$i]->product_type) ? $lines [$i]->product_type : 0); + + // Dates + // TODO mutualiser + $date_start = $lines [$i]->date_debut_prevue; + if ($lines [$i]->date_debut_reel) + $date_start = $lines [$i]->date_debut_reel; + if ($lines [$i]->date_start) + $date_start = $lines [$i]->date_start; + $date_end = $lines [$i]->date_fin_prevue; + if ($lines [$i]->date_fin_reel) + $date_end = $lines [$i]->date_fin_reel; + if ($lines [$i]->date_end) + $date_end = $lines [$i]->date_end; + + // Reset fk_parent_line for no child products and special product + if (($lines [$i]->product_type != 9 && empty($lines [$i]->fk_parent_line)) || $lines [$i]->product_type == 9) { + $fk_parent_line = 0; + } + + // Extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) // For avoid conflicts if + // trigger used + { + $lines [$i]->fetch_optionals($lines [$i]->rowid); + $array_option = $lines [$i]->array_options; + } + + $result = $object->addline($desc, $lines [$i]->subprice, $lines [$i]->qty, $lines [$i]->tva_tx, $lines [$i]->localtax1_tx, $lines [$i]->localtax2_tx, $lines [$i]->fk_product, $lines [$i]->remise_percent, $lines [$i]->info_bits, $lines [$i]->fk_remise_except, 'HT', 0, $date_start, $date_end, $product_type, $lines [$i]->rang, $lines [$i]->special_code, $fk_parent_line, $lines [$i]->fk_fournprice, $lines [$i]->pa_ht, $label, $array_option); + + if ($result < 0) { + $error ++; + break; + } + + // Defined the new fk_parent_line + if ($result > 0 && $lines [$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + + // Hooks + $parameters = array('objFrom' => $srcobject); + $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if ($reshook < 0) $error ++; - break; - } - - // Defined the new fk_parent_line - if ($result > 0 && $lines [$i]->product_type == 9) { - $fk_parent_line = $result; - } - } - - // Hooks - $parameters = array('objFrom' => $srcobject); - $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook - if ($reshook < 0) + } else { + setEventMessage($srcobject->error, 'errors'); $error ++; + } } else { - setEventMessage($srcobject->error, 'errors'); + setEventMessage($object->error, 'errors'); $error ++; } } else { - setEventMessage($object->error, 'errors'); - $error ++; + // Required extrafield left blank, error message already defined by setOptionalsFromPost() + $action = 'create'; } } else { - // Required extrafield left blank, error message already defined by setOptionalsFromPost() - $action = 'create'; - } - } else { - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) - $error ++; - - if (! $error) { - $object_id = $object->create($user); - - // If some invoice's lines already known - $NBLINES = 8; - for($i = 1; $i <= $NBLINES; $i ++) { - if ($_POST['idprod' . $i]) { - $xid = 'idprod' . $i; - $xqty = 'qty' . $i; - $xremise = 'remise_percent' . $i; - $object->add_product($_POST[$xid], $_POST[$xqty], $_POST[$xremise]); - } - } - } - } - - // Insert default contacts if defined - if ($object_id > 0) { - if (GETPOST('contactid')) { - $result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external'); - if ($result < 0) { - setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors'); + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) $error ++; - } - } - $id = $object_id; - $action = ''; - } + if (! $error) { + $object_id = $object->create($user); - // End of object creation, we show it - if ($object_id > 0 && ! $error) { - $db->commit(); - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object_id); - exit(); - } else { - $db->rollback(); - $action = 'create'; - setEventMessage($object->error, 'errors'); - } - } -} - -else if ($action == 'classifybilled' && $user->rights->commande->creer) -{ - $ret=$object->classifyBilled(); - - if ($ret < 0) { - setEventMessage($object->error, 'errors'); - } -} - -// Positionne ref commande client -else if ($action == 'set_ref_client' && $user->rights->commande->creer) { - $object->set_ref_client($user, GETPOST('ref_client')); -} - -else if ($action == 'setremise' && $user->rights->commande->creer) { - $object->set_remise($user, GETPOST('remise')); -} - -else if ($action == 'setabsolutediscount' && $user->rights->commande->creer) { - if (GETPOST('remise_id')) { - if ($object->id > 0) { - $object->insert_discount(GETPOST('remise_id')); - } else { - dol_print_error($db, $object->error); - } - } -} - -else if ($action == 'setdate' && $user->rights->commande->creer) { - // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; - $date = dol_mktime(0, 0, 0, GETPOST('order_month'), GETPOST('order_day'), GETPOST('order_year')); - - $result = $object->set_date($user, $date); - if ($result < 0) { - setEventMessage($object->error, 'errors'); - } -} - -else if ($action == 'setdate_livraison' && $user->rights->commande->creer) { - // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; - $datelivraison = dol_mktime(0, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); - - $result = $object->set_date_livraison($user, $datelivraison); - if ($result < 0) { - setEventMessage($object->error, 'errors'); - } -} - -else if ($action == 'setmode' && $user->rights->commande->creer) { - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setavailability' && $user->rights->commande->creer) { - $result = $object->availability(GETPOST('availability_id')); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setdemandreason' && $user->rights->commande->creer) { - $result = $object->demand_reason(GETPOST('demand_reason_id')); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setconditions' && $user->rights->commande->creer) { - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); - if ($result < 0) { - dol_print_error($db, $object->error); - } else { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - $newlang = GETPOST('lang_id', 'alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $ret = $object->fetch($object->id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } -} - -// bank account -else if ($action == 'setbankaccount' && $user->rights->commande->creer) { - $result=$object->setBankAccount(GETPOST('fk_account', 'int')); -} - -// shipping method -else if ($action == 'setshippingmethod' && $user->rights->commande->creer) { - $result = $object->setShippingMethod(GETPOST('shipping_method_id', 'int')); -} - -else if ($action == 'setremisepercent' && $user->rights->commande->creer) { - $result = $object->set_remise($user, GETPOST('remise_percent')); -} - -else if ($action == 'setremiseabsolue' && $user->rights->commande->creer) { - $result = $object->set_remise_absolue($user, GETPOST('remise_absolue')); -} - -// Add a new line -else if ($action == 'addline' && $user->rights->commande->creer) { - $langs->load('errors'); - $error = 0; - - // Set if we used free entry or predefined product - $predef=''; - $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); - $price_ht = GETPOST('price_ht'); - if (GETPOST('prod_entry_mode') == 'free') - { - $idprod=0; - $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - } - else - { - $idprod=GETPOST('idprod', 'int'); - $tva_tx = ''; - } - - $qty = GETPOST('qty' . $predef); - $remise_percent = GETPOST('remise_percent' . $predef); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key]); - } - } - - if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { - setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' - { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); - $error ++; - } - if ($qty == '') { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); - $error ++; - } - - if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { - // Clean parameters - $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); - $date_end=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); - $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); - - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - // Ecrase $base_price_type par celui du produit - if (! empty($idprod)) { - $prod = new Product($db); - $prod->fetch($idprod); - - $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); - - // Update if prices fields are defined - $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id); - $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id); - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - - // multiprix - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) - { - $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; - $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; - $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; - $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; - if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level]; - if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level]; - $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level]; - $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level]; - } - elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) - { - require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; - - $prodcustprice = new Productcustomerprice($db); - - $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); - - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); - if ($result >= 0) - { - if (count($prodcustprice->lines) > 0) - { - $pu_ht = price($prodcustprice->lines [0]->price); - $pu_ttc = price($prodcustprice->lines [0]->price_ttc); - $price_base_type = $prodcustprice->lines [0]->price_base_type; - $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; + // If some invoice's lines already known + $NBLINES = 8; + for($i = 1; $i <= $NBLINES; $i ++) { + if ($_POST['idprod' . $i]) { + $xid = 'idprod' . $i; + $xqty = 'qty' . $i; + $xremise = 'remise_percent' . $i; + $object->add_product($_POST[$xid], $_POST[$xqty], $_POST[$xremise]); } } - else - { - setEventMessage($prodcustprice->error,'errors'); + } + } + + // Insert default contacts if defined + if ($object_id > 0) { + if (GETPOST('contactid')) { + $result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external'); + if ($result < 0) { + setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors'); + $error ++; } } - // if price ht is forced (ie: calculated by margin rate and cost price) - if (! empty($price_ht)) { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } + $id = $object_id; + $action = ''; + } - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - elseif ($tva_tx != $prod->tva_tx) { - if ($price_base_type != 'HT') { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); - } else { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } - } - - $desc = ''; - - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $outputlangs = $langs; - $newlang = ''; - if (empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if (empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; - } else { - $desc = $prod->description; - } - - $desc = dol_concatdesc($desc, $product_desc); - - // Add custom code and origin country into description - if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { - $tmptxt = '('; - if (! empty($prod->customcode)) - $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; - if (! empty($prod->customcode) && ! empty($prod->country_code)) - $tmptxt .= ' - '; - if (! empty($prod->country_code)) - $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); - $tmptxt .= ')'; - $desc = dol_concatdesc($desc, $tmptxt); - } - - $type = $prod->type; - } else { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); - $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); - $tva_tx = str_replace('*', '', $tva_tx); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - $desc = $product_desc; - $type = GETPOST('type'); - } - - // Margin - $fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); - $buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); - - // Local Taxes - $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty); - $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty); - - $desc = dol_htmlcleanlastbr($desc); - - $info_bits = 0; - if ($tva_npr) - $info_bits |= 0x01; - - if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { - $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); - setEventMessage($mesg, 'errors'); - } else { - // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option); - - if ($result > 0) { - $ret = $object->fetch($object->id); // Reload to get new records - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - $newlang = GETPOST('lang_id', 'alpha'); - if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - unset($_POST['prod_entry_mode']); - - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); - unset($_POST['price_ttc']); - unset($_POST['tva_tx']); - unset($_POST['product_ref']); - unset($_POST['product_label']); - unset($_POST['product_desc']); - unset($_POST['fournprice']); - unset($_POST['buying_price']); - unset($_POST['np_marginRate']); - unset($_POST['np_markRate']); - unset($_POST['dp_desc']); - unset($_POST['idprod']); - - unset($_POST['date_starthour']); - unset($_POST['date_startmin']); - unset($_POST['date_startsec']); - unset($_POST['date_startday']); - unset($_POST['date_startmonth']); - unset($_POST['date_startyear']); - unset($_POST['date_endhour']); - unset($_POST['date_endmin']); - unset($_POST['date_endsec']); - unset($_POST['date_endday']); - unset($_POST['date_endmonth']); - unset($_POST['date_endyear']); + // End of object creation, we show it + if ($object_id > 0 && ! $error) { + $db->commit(); + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object_id); + exit(); } else { + $db->rollback(); + $action = 'create'; setEventMessage($object->error, 'errors'); } } } -} -/* - * Mise a jour d'une ligne dans la commande -*/ -else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('save') == $langs->trans('Save')) { - // Clean parameters - $date_start=''; - $date_end=''; - $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description=dol_htmlcleanlastbr(GETPOST('product_desc')); - $pu_ht=GETPOST('price_ht'); - $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); + else if ($action == 'classifybilled' && $user->rights->commande->creer) + { + $ret=$object->classifyBilled(); - // Define info_bits - $info_bits = 0; - if (preg_match('/\*/', $vat_rate)) - $info_bits |= 0x01; - - // Define vat_rate - $vat_rate = str_replace('*', '', $vat_rate); - $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty); - $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty); - - // Add buying price - $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : ''); - $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : ''); - - // Extrafields Lines - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); - // Unset extrafield POST Data - if (is_array($extralabelsline)) { - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key]); + if ($ret < 0) { + setEventMessage($object->error, 'errors'); } } - // Check minimum price - $productid = GETPOST('productid', 'int'); - if (! empty($productid)) { - $product = new Product($db); - $product->fetch($productid); + // Positionne ref commande client + else if ($action == 'set_ref_client' && $user->rights->commande->creer) { + $object->set_ref_client($user, GETPOST('ref_client')); + } - $type = $product->type; + else if ($action == 'setremise' && $user->rights->commande->creer) { + $object->set_remise($user, GETPOST('remise')); + } - $price_min = $product->price_min; - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) - $price_min = $product->multiprices_min [$object->thirdparty->price_level]; - - $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); - - if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); - $error ++; - } - } else { - $type = GETPOST('type'); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - - // Check parameters - if (GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); - $error ++; + else if ($action == 'setabsolutediscount' && $user->rights->commande->creer) { + if (GETPOST('remise_id')) { + if ($object->id > 0) { + $object->insert_discount(GETPOST('remise_id')); + } else { + dol_print_error($db, $object->error); + } } } - if (! $error) { - $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option); + else if ($action == 'setdate' && $user->rights->commande->creer) { + // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; + $date = dol_mktime(0, 0, 0, GETPOST('order_month'), GETPOST('order_day'), GETPOST('order_year')); - if ($result >= 0) { + $result = $object->set_date($user, $date); + if ($result < 0) { + setEventMessage($object->error, 'errors'); + } + } + + else if ($action == 'setdate_livraison' && $user->rights->commande->creer) { + // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; + $datelivraison = dol_mktime(0, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + + $result = $object->set_date_livraison($user, $datelivraison); + if ($result < 0) { + setEventMessage($object->error, 'errors'); + } + } + + else if ($action == 'setmode' && $user->rights->commande->creer) { + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); + if ($result < 0) + dol_print_error($db, $object->error); + } + + else if ($action == 'setavailability' && $user->rights->commande->creer) { + $result = $object->availability(GETPOST('availability_id')); + if ($result < 0) + dol_print_error($db, $object->error); + } + + else if ($action == 'setdemandreason' && $user->rights->commande->creer) { + $result = $object->demand_reason(GETPOST('demand_reason_id')); + if ($result < 0) + dol_print_error($db, $object->error); + } + + else if ($action == 'setconditions' && $user->rights->commande->creer) { + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + if ($result < 0) { + dol_print_error($db, $object->error); + } else { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { // Define output language $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); + $newlang = GETPOST('lang_id', 'alpha'); if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; if (! empty($newlang)) { @@ -857,348 +496,713 @@ else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST(' $ret = $object->fetch($object->id); // Reload to get new records $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['productid']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); - unset($_POST['price_ttc']); - unset($_POST['tva_tx']); - unset($_POST['product_ref']); - unset($_POST['product_label']); - unset($_POST['product_desc']); - unset($_POST['fournprice']); - unset($_POST['buying_price']); - } else { - setEventMessage($object->error, 'errors'); } } -} -else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('cancel') == $langs->trans('Cancel')) { - header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition - exit(); -} - -else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->commande->valider) { - $idwarehouse = GETPOST('idwarehouse'); - - $qualified_for_stock_change=0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) - { - $qualified_for_stock_change=$object->hasProductsOrServices(2); - } - else - { - $qualified_for_stock_change=$object->hasProductsOrServices(1); + // bank account + else if ($action == 'setbankaccount' && $user->rights->commande->creer) { + $result=$object->setBankAccount(GETPOST('fk_account', 'int')); } - // Check parameters - if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) - { - if (! $idwarehouse || $idwarehouse == -1) + // shipping method + else if ($action == 'setshippingmethod' && $user->rights->commande->creer) { + $result = $object->setShippingMethod(GETPOST('shipping_method_id', 'int')); + } + + else if ($action == 'setremisepercent' && $user->rights->commande->creer) { + $result = $object->set_remise($user, GETPOST('remise_percent')); + } + + else if ($action == 'setremiseabsolue' && $user->rights->commande->creer) { + $result = $object->set_remise_absolue($user, GETPOST('remise_absolue')); + } + + // Add a new line + else if ($action == 'addline' && $user->rights->commande->creer) { + $langs->load('errors'); + $error = 0; + + // Set if we used free entry or predefined product + $predef=''; + $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); + $price_ht = GETPOST('price_ht'); + if (GETPOST('prod_entry_mode') == 'free') { - $error++; - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors'); - $action=''; + $idprod=0; + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); } - } - - if (! $error) { - $result = $object->valid($user, $idwarehouse); - if ($result >= 0) - { - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records - - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } - } -} - -// Go back to draft status -else if ($action == 'confirm_modif' && $user->rights->commande->creer) { - $idwarehouse = GETPOST('idwarehouse'); - - $qualified_for_stock_change=0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) - { - $qualified_for_stock_change=$object->hasProductsOrServices(2); - } - else - { - $qualified_for_stock_change=$object->hasProductsOrServices(1); - } - - // Check parameters - if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) - { - if (! $idwarehouse || $idwarehouse == -1) - { - $error++; - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors'); - $action=''; - } - } - - if (! $error) { - $result = $object->set_draft($user, $idwarehouse); - if ($result >= 0) - { - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records - - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } - } -} - -else if ($action == 'confirm_shipped' && $confirm == 'yes' && $user->rights->commande->cloturer) { - $result = $object->cloture($user); - if ($result < 0) { - setEventMessage($object->error, 'errors'); - } -} - -else if ($action == 'confirm_cancel' && $confirm == 'yes' && $user->rights->commande->valider) { - $idwarehouse = GETPOST('idwarehouse'); - - $qualified_for_stock_change=0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) - { - $qualified_for_stock_change=$object->hasProductsOrServices(2); - } - else - { - $qualified_for_stock_change=$object->hasProductsOrServices(1); - } - - // Check parameters - if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) - { - if (! $idwarehouse || $idwarehouse == -1) - { - $error++; - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors'); - $action=''; - } - } - - if (! $error) { - $result = $object->cancel($idwarehouse); - - if ($result < 0) { - setEventMessage($object->error, 'errors'); - } - } -} - -/* - * Ordonnancement des lignes -*/ - -else if ($action == 'up' && $user->rights->commande->creer) { - $object->line_up(GETPOST('rowid')); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid')); - exit(); -} - -else if ($action == 'down' && $user->rights->commande->creer) { - $object->line_down(GETPOST('rowid')); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid')); - exit(); -} - -else if ($action == 'builddoc') // In get or post -{ - /* - * Generate order document - * define into /core/modules/commande/modules_commande.php - */ - - // Save last template used to generate document - if (GETPOST('model')) - $object->setDocModel($user, GETPOST('model', 'alpha')); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - - if ($result <= 0) { - dol_print_error($db, $result); - exit(); - } -} - -// Remove file in doc form -else if ($action == 'remove_file') { - if ($object->id > 0) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - $langs->load("other"); - $upload_dir = $conf->commande->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) - setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); else - setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); - $action = ''; + { + $idprod=GETPOST('idprod', 'int'); + $tva_tx = ''; + } + + $qty = GETPOST('qty' . $predef); + $remise_percent = GETPOST('remise_percent' . $predef); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { + setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' + { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); + $error ++; + } + if ($qty == '') { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); + $error ++; + } + + if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { + // Clean parameters + $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); + $date_end=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); + $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); + + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + // Ecrase $base_price_type par celui du produit + if (! empty($idprod)) { + $prod = new Product($db); + $prod->fetch($idprod); + + $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); + + // Update if prices fields are defined + $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id); + $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id); + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + + // multiprix + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) + { + $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; + $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; + if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level]; + if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level]; + $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level]; + $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level]; + } + elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + + $prodcustprice = new Productcustomerprice($db); + + $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result >= 0) + { + if (count($prodcustprice->lines) > 0) + { + $pu_ht = price($prodcustprice->lines [0]->price); + $pu_ttc = price($prodcustprice->lines [0]->price_ttc); + $price_base_type = $prodcustprice->lines [0]->price_base_type; + $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; + } + } + else + { + setEventMessage($prodcustprice->error,'errors'); + } + } + + // if price ht is forced (ie: calculated by margin rate and cost price) + if (! empty($price_ht)) { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + elseif ($tva_tx != $prod->tva_tx) { + if ($price_base_type != 'HT') { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); + } else { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + } + + $desc = ''; + + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if (empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; + } else { + $desc = $prod->description; + } + + $desc = dol_concatdesc($desc, $product_desc); + + // Add custom code and origin country into description + if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { + $tmptxt = '('; + if (! empty($prod->customcode)) + $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; + if (! empty($prod->customcode) && ! empty($prod->country_code)) + $tmptxt .= ' - '; + if (! empty($prod->country_code)) + $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); + $tmptxt .= ')'; + $desc = dol_concatdesc($desc, $tmptxt); + } + + $type = $prod->type; + } else { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); + $tva_tx = str_replace('*', '', $tva_tx); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + $desc = $product_desc; + $type = GETPOST('type'); + } + + // Margin + $fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); + $buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); + + // Local Taxes + $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty); + $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty); + + $desc = dol_htmlcleanlastbr($desc); + + $info_bits = 0; + if ($tva_npr) + $info_bits |= 0x01; + + if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { + $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); + setEventMessage($mesg, 'errors'); + } else { + // Insert line + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option); + + if ($result > 0) { + $ret = $object->fetch($object->id); // Reload to get new records + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = GETPOST('lang_id', 'alpha'); + if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST['prod_entry_mode']); + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); + unset($_POST['np_marginRate']); + unset($_POST['np_markRate']); + unset($_POST['dp_desc']); + unset($_POST['idprod']); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); + } else { + setEventMessage($object->error, 'errors'); + } + } + } } -} -else if ($action == 'update_extras') { - // Fill array 'array_options' with data from update form - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); - if ($ret < 0) - $error ++; + /* + * Mise a jour d'une ligne dans la commande + */ + else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('save') == $langs->trans('Save')) { + // Clean parameters + $date_start=''; + $date_end=''; + $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + $description=dol_htmlcleanlastbr(GETPOST('product_desc')); + $pu_ht=GETPOST('price_ht'); + $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); - if (! $error) { - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('orderdao')); - $parameters = array('id' => $object->id); - $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by - // some hooks - if (empty($reshook)) { - $result = $object->insertExtraFields(); - if ($result < 0) { + // Define info_bits + $info_bits = 0; + if (preg_match('/\*/', $vat_rate)) + $info_bits |= 0x01; + + // Define vat_rate + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty); + $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty); + + // Add buying price + $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : ''); + $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : ''); + + // Extrafields Lines + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield POST Data + if (is_array($extralabelsline)) { + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + // Check minimum price + $productid = GETPOST('productid', 'int'); + if (! empty($productid)) { + $product = new Product($db); + $product->fetch($productid); + + $type = $product->type; + + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) + $price_min = $product->multiprices_min [$object->thirdparty->price_level]; + + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); + + if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { + setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); $error ++; } - } else if ($reshook < 0) - $error ++; - } + } else { + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - if ($error) - $action = 'edit_extras'; -} - -include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; - - -/* - * Send mail - */ - -// Actions to send emails -$actiontypecode='AC_COM'; -$trigger_name='ORDER_SENTBYMAIL'; -$paramname='id'; -$mode='emailfromorder'; -include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; - - - -if (! $error && ! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->commande->creer) { - if ($action == 'addcontact') { - if ($object->id > 0) { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, GETPOST('type'), GETPOST('source')); + // Check parameters + if (GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); + $error ++; + } } - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit(); - } else { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - $langs->load("errors"); - setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors'); + if (! $error) { + $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option); + + if ($result >= 0) { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $ret = $object->fetch($object->id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['productid']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); } else { setEventMessage($object->error, 'errors'); } } } - // bascule du statut d'un contact - else if ($action == 'swapstatut') { - if ($object->id > 0) { - $result = $object->swapContactStatus(GETPOST('ligne')); - } else { - dol_print_error($db); + else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('cancel') == $langs->trans('Cancel')) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition + exit(); + } + + else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->commande->valider) { + $idwarehouse = GETPOST('idwarehouse'); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + + // Check parameters + if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors'); + $action=''; + } + } + + if (! $error) { + $result = $object->valid($user, $idwarehouse); + if ($result >= 0) + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } } } - // Efface un contact - else if ($action == 'deletecontact') { - $result = $object->delete_contact($lineid); + // Go back to draft status + else if ($action == 'confirm_modif' && $user->rights->commande->creer) { + $idwarehouse = GETPOST('idwarehouse'); - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + + // Check parameters + if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors'); + $action=''; + } + } + + if (! $error) { + $result = $object->set_draft($user, $idwarehouse); + if ($result >= 0) + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + } + } + + else if ($action == 'confirm_shipped' && $confirm == 'yes' && $user->rights->commande->cloturer) { + $result = $object->cloture($user); + if ($result < 0) { + setEventMessage($object->error, 'errors'); + } + } + + else if ($action == 'confirm_cancel' && $confirm == 'yes' && $user->rights->commande->valider) { + $idwarehouse = GETPOST('idwarehouse'); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + + // Check parameters + if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors'); + $action=''; + } + } + + if (! $error) { + $result = $object->cancel($idwarehouse); + + if ($result < 0) { + setEventMessage($object->error, 'errors'); + } + } + } + + /* + * Ordonnancement des lignes + */ + + else if ($action == 'up' && $user->rights->commande->creer) { + $object->line_up(GETPOST('rowid')); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid')); + exit(); + } + + else if ($action == 'down' && $user->rights->commande->creer) { + $object->line_down(GETPOST('rowid')); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid')); + exit(); + } + + else if ($action == 'builddoc') // In get or post + { + /* + * Generate order document + * define into /core/modules/commande/modules_commande.php + */ + + // Save last template used to generate document + if (GETPOST('model')) + $object->setDocModel($user, GETPOST('model', 'alpha')); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + + if ($result <= 0) { + dol_print_error($db, $result); exit(); - } else { - dol_print_error($db); + } + } + + // Remove file in doc form + else if ($action == 'remove_file') { + if ($object->id > 0) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $langs->load("other"); + $upload_dir = $conf->commande->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret = dol_delete_file($file, 0, 0, 0, $object); + if ($ret) + setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else + setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + $action = ''; + } + } + + else if ($action == 'update_extras') { + // Fill array 'array_options' with data from update form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) + $error ++; + + if (! $error) { + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('orderdao')); + $parameters = array('id' => $object->id); + $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by + // some hooks + if (empty($reshook)) { + $result = $object->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } else if ($reshook < 0) + $error ++; + } + + if ($error) + $action = 'edit_extras'; + } + + include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; + + + /* + * Send mail + */ + + // Actions to send emails + $actiontypecode='AC_COM'; + $trigger_name='ORDER_SENTBYMAIL'; + $paramname='id'; + $mode='emailfromorder'; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + + + + if (! $error && ! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->commande->creer) { + if ($action == 'addcontact') { + if ($object->id > 0) { + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, GETPOST('type'), GETPOST('source')); + } + + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); + } else { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors'); + } else { + setEventMessage($object->error, 'errors'); + } + } + } + + // bascule du statut d'un contact + else if ($action == 'swapstatut') { + if ($object->id > 0) { + $result = $object->swapContactStatus(GETPOST('ligne')); + } else { + dol_print_error($db); + } + } + + // Efface un contact + else if ($action == 'deletecontact') { + $result = $object->delete_contact($lineid); + + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); + } else { + dol_print_error($db); + } } } } + /* * View */ diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 967402b8d94..8a7005c9fea 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -140,26 +140,25 @@ class Commande extends CommonOrder if (! empty($conf->global->COMMANDE_ADDON)) { - $mybool=false; - $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); - foreach ($dirmodels as $reldir) - { - $file = $conf->global->COMMANDE_ADDON.".php"; - $classname = $conf->global->COMMANDE_ADDON; + $mybool=false; - // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot.$reldir."/core/modules/commande/"; - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } - } + $file = $conf->global->COMMANDE_ADDON.".php"; + $classname = $conf->global->COMMANDE_ADDON; + + // Include file with class + $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/commande/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } if (! $mybool) { - dol_print_error('',"Failed to include file ".$file); - return ''; + dol_print_error('',"Failed to include file ".$file); + return ''; } $obj = new $classname(); diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index adb46ecdae9..13e8fa381fe 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -106,6 +106,7 @@ $hookmanager->initHooks(array('invoicecard','globalcard')); $permissionnote = $user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php + /* * Actions */ @@ -114,1253 +115,383 @@ $parameters = array('socid' => $socid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once +if (empty($reshook)) +{ + include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once -// Action clone object -if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer) { -// if (1 == 0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) { -// $mesgs [] = '
' . $langs->trans("NoCloneOptionsSpecified") . '
'; -// } else { - if ($object->fetch($id) > 0) { - $result = $object->createFromClone($socid); + // Action clone object + if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer) { + // if (1 == 0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) { + // $mesgs [] = '
' . $langs->trans("NoCloneOptionsSpecified") . '
'; + // } else { + if ($object->fetch($id) > 0) { + $result = $object->createFromClone($socid); + if ($result > 0) { + header("Location: " . $_SERVER['PHP_SELF'] . '?facid=' . $result); + exit(); + } else { + setEventMessage($object->error, 'errors'); + $action = ''; + } + } + // } + } + + // Change status of invoice + else if ($action == 'reopen' && $user->rights->facture->creer) { + $result = $object->fetch($id); + if ($object->statut == 2 || ($object->statut == 3 && $object->close_code != 'replaced')) { + $result = $object->set_unpaid($user); if ($result > 0) { - header("Location: " . $_SERVER['PHP_SELF'] . '?facid=' . $result); + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); exit(); } else { setEventMessage($object->error, 'errors'); - $action = ''; } } -// } -} + } -// Change status of invoice -else if ($action == 'reopen' && $user->rights->facture->creer) { - $result = $object->fetch($id); - if ($object->statut == 2 || ($object->statut == 3 && $object->close_code != 'replaced')) { - $result = $object->set_unpaid($user); + // Delete invoice + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer) { + $result = $object->fetch($id); + $object->fetch_thirdparty(); + + $idwarehouse = GETPOST('idwarehouse'); + + $qualified_for_stock_change = 0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + $qualified_for_stock_change = $object->hasProductsOrServices(2); + } else { + $qualified_for_stock_change = $object->hasProductsOrServices(1); + } + + $result = $object->delete(0, 0, $idwarehouse); if ($result > 0) { - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); + header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php'); exit(); } else { setEventMessage($object->error, 'errors'); + $action=''; } } -} -// Delete invoice -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer) { - $result = $object->fetch($id); - $object->fetch_thirdparty(); - - $idwarehouse = GETPOST('idwarehouse'); - - $qualified_for_stock_change = 0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $qualified_for_stock_change = $object->hasProductsOrServices(2); - } else { - $qualified_for_stock_change = $object->hasProductsOrServices(1); - } - - $result = $object->delete(0, 0, $idwarehouse); - if ($result > 0) { - header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php'); - exit(); - } else { - setEventMessage($object->error, 'errors'); - $action=''; - } -} - -// Delete line -else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer) -{ - $object->fetch($id); - $object->fetch_thirdparty(); - - $result = $object->deleteline(GETPOST('lineid')); - if ($result > 0) { - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $ret = $object->fetch($id); // Reload to get new records - $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - if ($result >= 0) { - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); - exit(); - } - } else { - setEventMessage($object->error, 'errors'); - $action = ''; - } -} - -// Delete link of credit note to invoice -else if ($action == 'unlinkdiscount' && $user->rights->facture->creer) -{ - $discount = new DiscountAbsolute($db); - $result = $discount->fetch(GETPOST("discountid")); - $discount->unlink_invoice(); -} - -// Validation -else if ($action == 'valid' && $user->rights->facture->creer) -{ - $object->fetch($id); - - // On verifie signe facture - if ($object->type == Facture::TYPE_CREDIT_NOTE) { - // Si avoir, le signe doit etre negatif - if ($object->total_ht >= 0) { - setEventMessage($langs->trans("ErrorInvoiceAvoirMustBeNegative"), 'errors'); - $action = ''; - } - } else { - // Si non avoir, le signe doit etre positif - if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) { - setEventMessage($langs->trans("ErrorInvoiceOfThisTypeMustBePositive"), 'errors'); - $action = ''; - } - } -} - -else if ($action == 'set_thirdparty' && $user->rights->facture->creer) -{ - $object->fetch($id); - $object->setValueFrom('fk_soc', $socid); - - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); - exit(); -} - -else if ($action == 'classin' && $user->rights->facture->creer) -{ - $object->fetch($id); - $object->setProject($_POST['projectid']); -} - -else if ($action == 'setmode' && $user->rights->facture->creer) -{ - $object->fetch($id); - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setinvoicedate' && $user->rights->facture->creer) -{ - $object->fetch($id); - $old_date_lim_reglement = $object->date_lim_reglement; - $date = dol_mktime(12, 0, 0, $_POST['invoicedatemonth'], $_POST['invoicedateday'], $_POST['invoicedateyear']); - if (empty($date)) + // Delete line + else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer) { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id.'&action=editinvoicedate'); - exit; - } - $object->date=$date; - $new_date_lim_reglement = $object->calculate_date_lim_reglement(); - if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement; - if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date; - $result = $object->update($user); - if ($result < 0) dol_print_error($db, $object->error); -} + $object->fetch($id); + $object->fetch_thirdparty(); -else if ($action == 'setconditions' && $user->rights->facture->creer) -{ - $object->fetch($id); - $object->cond_reglement_code = 0; // To clean property - $object->cond_reglement_id = 0; // To clean property - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); - if ($result < 0) dol_print_error($db, $object->error); - - $old_date_lim_reglement = $object->date_lim_reglement; - $new_date_lim_reglement = $object->calculate_date_lim_reglement(); - if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement; - if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date; - $result = $object->update($user); - if ($result < 0) dol_print_error($db, $object->error); -} - -else if ($action == 'setpaymentterm' && $user->rights->facture->creer) -{ - $object->fetch($id); - $object->date_lim_reglement = dol_mktime(12, 0, 0, $_POST['paymenttermmonth'], $_POST['paymenttermday'], $_POST['paymenttermyear']); - if ($object->date_lim_reglement < $object->date) { - $object->date_lim_reglement = $object->calculate_date_lim_reglement(); - setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), 'warnings'); - } - $result = $object->update($user); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setrevenuestamp' && $user->rights->facture->creer) -{ - $object->fetch($id); - $object->revenuestamp = GETPOST('revenuestamp'); - $result = $object->update($user); - $object->update_price(1); - if ($result < 0) - dol_print_error($db, $object->error); -} - -// bank account -else if ($action == 'setbankaccount' && $user->rights->facture->creer) -{ - $result=$object->setBankAccount(GETPOST('fk_account', 'int')); -} - -else if ($action == 'setremisepercent' && $user->rights->facture->creer) -{ - $object->fetch($id); - $result = $object->set_remise($user, $_POST['remise_percent']); -} - -else if ($action == "setabsolutediscount" && $user->rights->facture->creer) -{ - // POST[remise_id] ou POST[remise_id_for_payment] - if (! empty($_POST["remise_id"])) { - $ret = $object->fetch($id); - if ($ret > 0) { - $result = $object->insert_discount($_POST["remise_id"]); - if ($result < 0) { - setEventMessage($object->error, 'errors'); + $result = $object->deleteline(GETPOST('lineid')); + if ($result > 0) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $ret = $object->fetch($id); // Reload to get new records + $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + if ($result >= 0) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); + exit(); } } else { - dol_print_error($db, $object->error); + setEventMessage($object->error, 'errors'); + $action = ''; } } - if (! empty($_POST["remise_id_for_payment"])) { - require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php'; + + // Delete link of credit note to invoice + else if ($action == 'unlinkdiscount' && $user->rights->facture->creer) + { $discount = new DiscountAbsolute($db); - $discount->fetch($_POST["remise_id_for_payment"]); - - $result = $discount->link_to_invoice(0, $id); - if ($result < 0) { - setEventMessage($discount->error, 'errors'); - } + $result = $discount->fetch(GETPOST("discountid")); + $discount->unlink_invoice(); } -} -else if ($action == 'set_ref_client' && $user->rights->facture->creer) -{ - $object->fetch($id); - $object->set_ref_client($_POST['ref_client']); -} - -// Classify to validated -else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider) -{ - $idwarehouse = GETPOST('idwarehouse'); - - $object->fetch($id); - $object->fetch_thirdparty(); - - // Check parameters - - // Check for mandatory prof id - for($i = 1; $i < 6; $i ++) + // Validation + else if ($action == 'valid' && $user->rights->facture->creer) { - $idprof_mandatory = 'SOCIETE_IDPROF' . ($i) . '_INVOICE_MANDATORY'; - $idprof = 'idprof' . $i; - if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory)) - { - if (! $error) - $langs->load("errors"); - $error ++; + $object->fetch($id); - setEventMessage($langs->trans('ErrorProdIdIsMandatory', $langs->transcountry('ProfId' . $i, $object->thirdparty->country_code)), 'errors'); - } - } - - $qualified_for_stock_change = 0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $qualified_for_stock_change = $object->hasProductsOrServices(2); - } else { - $qualified_for_stock_change = $object->hasProductsOrServices(1); - } - - // Check for warehouse - if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) - { - if (! $idwarehouse || $idwarehouse == - 1) { - $error ++; - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), 'errors'); - $action = ''; - } - } - - if (! $error) - { - $result = $object->validate($user, '', $idwarehouse); - if ($result >= 0) - { - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records - - $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result < 0) dol_print_error($db,$result); - } - } - else - { - if (count($object->errors)) setEventMessage($object->errors, 'errors'); - else setEventMessage($object->error, 'errors'); - } - } -} - -// Go back to draft status (unvalidate) -else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)) -{ - $idwarehouse = GETPOST('idwarehouse'); - - $object->fetch($id); - $object->fetch_thirdparty(); - - $qualified_for_stock_change = 0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $qualified_for_stock_change = $object->hasProductsOrServices(2); - } else { - $qualified_for_stock_change = $object->hasProductsOrServices(1); - } - - // Check parameters - if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) - { - if (! $idwarehouse || $idwarehouse == - 1) { - $error ++; - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), 'errors'); - $action = ''; - } - } - - if (! $error) { - // On verifie si la facture a des paiements - $sql = 'SELECT pf.amount'; - $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture as pf'; - $sql .= ' WHERE pf.fk_facture = ' . $object->id; - - $result = $db->query($sql); - if ($result) { - $i = 0; - $num = $db->num_rows($result); - - while ($i < $num) { - $objp = $db->fetch_object($result); - $totalpaye += $objp->amount; - $i ++; + // On verifie signe facture + if ($object->type == Facture::TYPE_CREDIT_NOTE) { + // Si avoir, le signe doit etre negatif + if ($object->total_ht >= 0) { + setEventMessage($langs->trans("ErrorInvoiceAvoirMustBeNegative"), 'errors'); + $action = ''; } } else { - dol_print_error($db, ''); - } - - $resteapayer = $object->total_ttc - $totalpaye; - - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = $object->getVentilExportCompta(); - - // On verifie si aucun paiement n'a ete effectue - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) - { - $result=$object->set_draft($user, $idwarehouse); - if ($result<0) setEventMessage($object->error,'errors'); - - - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records - - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + // Si non avoir, le signe doit etre positif + if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) { + setEventMessage($langs->trans("ErrorInvoiceOfThisTypeMustBePositive"), 'errors'); + $action = ''; } } } -} -// Classify "paid" -else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement) -{ - $object->fetch($id); - $result = $object->set_paid($user); - if ($result<0) setEventMessage($object->error,'errors'); -} // Classif "paid partialy" -else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement) -{ - $object->fetch($id); - $close_code = $_POST["close_code"]; - $close_note = $_POST["close_note"]; - if ($close_code) { - $result = $object->set_paid($user, $close_code, $close_note); - if ($result<0) setEventMessage($object->error,'errors'); - } else { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors'); - } -} // Classify "abandoned" -else if ($action == 'confirm_canceled' && $confirm == 'yes') { - $object->fetch($id); - $close_code = $_POST["close_code"]; - $close_note = $_POST["close_note"]; - if ($close_code) { - $result = $object->set_canceled($user, $close_code, $close_note); - if ($result<0) setEventMessage($object->error,'errors'); - } else { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors'); - } -} - -// Convertir en reduc -else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer) -{ - $object->fetch($id); - $object->fetch_thirdparty(); - //$object->fetch_lines(); // Already done into fetch - - // Check if there is already a discount (protection to avoid duplicate creation when resubmit post) - $discountcheck=new DiscountAbsolute($db); - $result=$discountcheck->fetch(0,$object->id); - - $canconvert=0; - if ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 1 && empty($discountcheck->id)) $canconvert=1; // we can convert deposit into discount if deposit is payed completely and not already converted (see real condition into condition used to show button converttoreduc) - if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) - if ($canconvert) + else if ($action == 'set_thirdparty' && $user->rights->facture->creer) { - $db->begin(); + $object->fetch($id); + $object->setValueFrom('fk_soc', $socid); - // Boucle sur chaque taux de tva - $i = 0; - foreach ($object->lines as $line) { - $amount_ht [$line->tva_tx] += $line->total_ht; - $amount_tva [$line->tva_tx] += $line->total_tva; - $amount_ttc [$line->tva_tx] += $line->total_ttc; - $i ++; - } - - // Insert one discount by VAT rate category - $discount = new DiscountAbsolute($db); - if ($object->type == Facture::TYPE_CREDIT_NOTE) - $discount->description = '(CREDIT_NOTE)'; - elseif ($object->type == Facture::TYPE_DEPOSIT) - $discount->description = '(DEPOSIT)'; - else { - setEventMessage($langs->trans('CantConvertToReducAnInvoiceOfThisType'),'errors'); - } - $discount->tva_tx = abs($object->total_ttc); - $discount->fk_soc = $object->socid; - $discount->fk_facture_source = $object->id; - - $error = 0; - foreach ($amount_ht as $tva_tx => $xxx) { - $discount->amount_ht = abs($amount_ht [$tva_tx]); - $discount->amount_tva = abs($amount_tva [$tva_tx]); - $discount->amount_ttc = abs($amount_ttc [$tva_tx]); - $discount->tva_tx = abs($tva_tx); - - $result = $discount->create($user); - if ($result < 0) - { - $error++; - break; - } - } - - if (empty($error)) - { - // Classe facture - $result = $object->set_paid($user); - if ($result >= 0) - { - $db->commit(); - } - else - { - setEventMessage($object->error,'errors'); - $db->rollback(); - } - } - else - { - setEventMessage($discount->error,'errors'); - $db->rollback(); - } - } -} - -/* - * Insert new invoice in database -*/ -else if ($action == 'add' && $user->rights->facture->creer) -{ - if ($socid > 0) $object->socid = GETPOST('socid', 'int'); - - $db->begin(); - - $error = 0; - - // Fill array 'array_options' with data from add form - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) $error ++; - - // Replacement invoice - if ($_POST['type'] == Facture::TYPE_REPLACEMENT) - { - $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($dateinvoice)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } - - if (! ($_POST['fac_replacement'] > 0)) { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), 'errors'); - } - - if (! $error) { - // This is a replacement invoice - $result = $object->fetch($_POST['fac_replacement']); - $object->fetch_thirdparty(); - - $object->date = $dateinvoice; - $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = $_POST['cond_reglement_id']; - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->fk_account = GETPOST('fk_account', 'int'); - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; - - // Proprietes particulieres a facture de remplacement - $object->fk_facture_source = $_POST['fac_replacement']; - $object->type = Facture::TYPE_REPLACEMENT; - - $id = $object->createFromCurrent($user); - if ($id <= 0) { - setEventMessage($object->error, 'errors'); - } - } - } - - // Credit note invoice - if ($_POST['type'] == Facture::TYPE_CREDIT_NOTE) - { - if (! ($_POST['fac_avoir'] > 0)) - { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), 'errors'); - } - - $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($dateinvoice)) - { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->trans("Date")), 'errors'); - } - - if (! $error) - { - $object->socid = GETPOST('socid','int'); - $object->number = $_POST['facnumber']; - $object->date = $dateinvoice; - $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = 0; - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->fk_account = GETPOST('fk_account', 'int'); - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; - - // Proprietes particulieres a facture avoir - $object->fk_facture_source = $_POST['fac_avoir']; - $object->type = Facture::TYPE_CREDIT_NOTE; - - $id = $object->create($user); - - if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0) - { - $facture_source = new Facture($db); // fetch origin object - if ($facture_source->fetch($object->fk_facture_source)>0) - { - - foreach($facture_source->lines as $line) - { - $line->fk_facture = $object->id; - - $line->subprice =-$line->subprice; // invert price for object - $line->pa_ht = -$line->pa_ht; - $line->total_ht=-$line->total_ht; - $line->total_tva=-$line->total_tva; - $line->total_ttc=-$line->total_ttc; - $line->total_localtax1=-$line->total_localtax1; - $line->total_localtax2=-$line->total_localtax2; - - $line->insert(); - - $object->lines[] = $line; // insert new line in current object - } - - $object->update_price(1); - } - - } - - if(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int')==1 && $id>0) - { - $facture_source = new Facture($db); // fetch origin object if not previously defined - if ($facture_source->fetch($object->fk_facture_source)>0) - { - $totalpaye = $facture_source->getSommePaiement(); - $totalcreditnotes = $facture_source->getSumCreditNotesUsed(); - $totaldeposits = $facture_source->getSumDepositsUsed(); - $remain_to_pay = abs($facture_source->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits); - - $object->addline($langs->trans('invoiceAvoirLineWithPaymentRestAmount'),$remain_to_pay,1,0,0,0,0,0,'','','TTC'); - } - } - - // Add predefined lines - /* - TODO delete - for($i = 1; $i <= $NBLINES; $i ++) { - if ($_POST['idprod' . $i]) { - $product = new Product($db); - $product->fetch($_POST['idprod' . $i]); - $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']); - $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']); - $result = $object->addline($product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); - } - }*/ - } - } - - // Standard invoice or Deposit invoice created from a Predefined invoice - if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT) && $_POST['fac_rec'] > 0) - { - $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($dateinvoice)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } - - if (! $error) - { - $object->socid = GETPOST('socid','int'); - $object->type = $_POST['type']; - $object->number = $_POST['facnumber']; - $object->date = $dateinvoice; - $object->note_public = trim($_POST['note_public']); - $object->note_private = trim($_POST['note_private']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - - // Source facture - $object->fac_rec = $_POST['fac_rec']; - - $id = $object->create($user); - } - } - - // Standard or deposit or proforma invoice - if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT || $_POST['type'] == Facture::TYPE_PROFORMA || ($_POST['type'] == Facture::TYPE_SITUATION && empty($_POST['situations']))) && $_POST['fac_rec'] <= 0) - { - if (GETPOST('socid', 'int') < 1) - { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); - } - - $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($dateinvoice)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } - - if (! $error) - { - // Si facture standard - $object->socid = GETPOST('socid','int'); - $object->type = GETPOST('type'); - $object->number = $_POST['facnumber']; - $object->date = $dateinvoice; - $object->note_public = trim($_POST['note_public']); - $object->note_private = trim($_POST['note_private']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']); - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->fk_account = GETPOST('fk_account', 'int'); - $object->amount = $_POST['amount']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; - - if($_POST['type'] == Facture::TYPE_SITUATION) { - $object->situation_counter = 1; - $object->situation_final = 0; - $object->situation_cycle_ref = $object->newCycle(); - } - - $object->fetch_thirdparty(); - - // If creation from another object of another module (Example: origin=propal, originid=1) - if ($origin && $originid) - { - // Parse element/subelement (ex: project_task) - $element = $subelement = $origin; - if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { - $element = $regs [1]; - $subelement = $regs [2]; - } - - // For compatibility - if ($element == 'order') { - $element = $subelement = 'commande'; - } - if ($element == 'propal') { - $element = 'comm/propal'; - $subelement = 'propal'; - } - if ($element == 'contract') { - $element = $subelement = 'contrat'; - } - if ($element == 'inter') { - $element = $subelement = 'ficheinter'; - } - if ($element == 'shipping') { - $element = $subelement = 'expedition'; - } - - $object->origin = $origin; - $object->origin_id = $originid; - - // Possibility to add external linked objects with hooks - $object->linked_objects[$object->origin] = $object->origin_id; - // link with order if it is a shipping invoice - if ($object->origin == 'shipping') - { - require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php'; - $exp = new Expedition($db); - $exp->fetch($object->origin_id); - $exp->fetchObjectLinked(); - if (count($exp->linkedObjectsIds['commande']) > 0) $object->linked_objects['commande'] = $exp->linkedObjectsIds['commande'][0]; - } - - if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) - { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); - } - - $id = $object->create($user); - - if ($id > 0) - { - // If deposit invoice - if ($_POST['type'] == Facture::TYPE_DEPOSIT) - { - $typeamount = GETPOST('typedeposit', 'alpha'); - $valuedeposit = GETPOST('valuedeposit', 'int'); - - if ($typeamount == 'amount') - { - $amountdeposit = $valuedeposit; - } - else - { - $amountdeposit = 0; - - dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); - - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add deposit lines"); - $result = $srcobject->fetch($object->origin_id); - if ($result > 0) - { - $totalamount = 0; - $lines = $srcobject->lines; - $numlines=count($lines); - for ($i=0; $i<$numlines; $i++) - { - $qualified=1; - if (empty($lines[$i]->qty)) $qualified=0; // We discard qty=0, it is an option - if (! empty($lines[$i]->special_code)) $qualified=0; // We discard special_code (frais port, ecotaxe, option, ...) - if ($qualified) $totalamount += $lines[$i]->total_ht; - } - - if ($totalamount != 0) { - $amountdeposit = ($totalamount * $valuedeposit) / 100; - } - } else { - setEventMessage($srcobject->error, 'errors'); - $error ++; - } - } - - $result = $object->addline( - $langs->trans('Deposit'), - $amountdeposit, // subprice - 1, // quantity - $lines[$i]->tva_tx, 0, // localtax1_tx - 0, // localtax2_tx - 0, // fk_product - 0, // remise_percent - 0, // date_start - 0, // date_end - 0, $lines[$i]->info_bits, // info_bits - 0, // info_bits - 'HT', - 0, - 0, // product_type - 1, - $lines[$i]->special_code, - $object->origin, - 0, - 0, - 0, - 0, - $langs->trans('Deposit') - ); - } - else - { - - dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); - - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); - $result = $srcobject->fetch($object->origin_id); - if ($result > 0) - { - $lines = $srcobject->lines; - if (empty($lines) && method_exists($srcobject, 'fetch_lines')) - { - $srcobject->fetch_lines(); - $lines = $srcobject->lines; - } - - $fk_parent_line=0; - $num=count($lines); - for ($i=0;$i<$num;$i++) - { - // Don't add lines with qty 0 when coming from a shipment including all order lines - if($srcobject->element == 'shipping' && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS && $lines[$i]->qty == 0) continue; - - $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); - $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); - if ($object->situation_counter == 1) $lines[$i]->situation_percent = 0; - - if ($lines[$i]->subprice < 0) - { - // Negative line, we create a discount line - $discount = new DiscountAbsolute($db); - $discount->fk_soc = $object->socid; - $discount->amount_ht = abs($lines[$i]->total_ht); - $discount->amount_tva = abs($lines[$i]->total_tva); - $discount->amount_ttc = abs($lines[$i]->total_ttc); - $discount->tva_tx = $lines[$i]->tva_tx; - $discount->fk_user = $user->id; - $discount->description = $desc; - $discountid = $discount->create($user); - if ($discountid > 0) { - $result = $object->insert_discount($discountid); // This include link_to_invoice - } else { - setEventMessage($discount->error, 'errors'); - $error ++; - break; - } - } else { - // Positive line - $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0); - - // Date start - $date_start = false; - if ($lines[$i]->date_debut_prevue) - $date_start = $lines[$i]->date_debut_prevue; - if ($lines[$i]->date_debut_reel) - $date_start = $lines[$i]->date_debut_reel; - if ($lines[$i]->date_start) - $date_start = $lines[$i]->date_start; - - // Date end - $date_end = false; - if ($lines[$i]->date_fin_prevue) - $date_end = $lines[$i]->date_fin_prevue; - if ($lines[$i]->date_fin_reel) - $date_end = $lines[$i]->date_fin_reel; - if ($lines[$i]->date_end) - $date_end = $lines[$i]->date_end; - - // Reset fk_parent_line for no child products and special product - if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { - $fk_parent_line = 0; - } - - // Extrafields - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) { - $lines[$i]->fetch_optionals($lines[$i]->rowid); - $array_option = $lines[$i]->array_options; - } - - $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $object->origin, $lines[$i]->rowid, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_option, $lines[$i]->situation_percent, $lines[$i]->fk_prev_id); - - if ($result > 0) { - $lineid = $result; - } else { - $lineid = 0; - $error ++; - break; - } - - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { - $fk_parent_line = $result; - } - } - } - - // Hooks - $parameters = array('objFrom' => $srcobject); - $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook - if ($reshook < 0) - $error ++; - } else { - setEventMessage($srcobject->error, 'errors'); - $error ++; - } - } - } else { - setEventMessage($object->error, 'errors'); - $error ++; - } - } // If some invoice's lines already known - else { - $id = $object->create($user); - - for($i = 1; $i <= $NBLINES; $i ++) { - if ($_POST['idprod' . $i]) { - $product = new Product($db); - $product->fetch($_POST['idprod' . $i]); - $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']); - $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']); - $result = $object->addline($product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); - } - } - } - } - } - - if ($_POST['type'] == Facture::TYPE_SITUATION && (!empty($_POST['situations']))) { - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) { - $error++; - $mesg = '
' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '
'; - } - - if (!($_POST['situations'] > 0)) { - $error++; - $mesg = '
' . $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation")) . '
'; - } - - if (!$error) { - $result = $object->fetch($_POST['situations']); - $object->fk_facture_source = $_POST['situations']; - $object->type = Facture::TYPE_SITUATION; - - $object->fetch_thirdparty(); - $object->date = $datefacture; - $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = $_POST['cond_reglement_id']; - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; - - // Proprietes particulieres a facture de remplacement - - $object->situation_counter = $object->situation_counter + 1; - $id = $object->createFromCurrent($user); - if ($id <= 0) $mesg = $object->error; - } - } - - // End of object creation, we show it - if ($id > 0 && ! $error) - { - $db->commit(); header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); exit(); } - else + + else if ($action == 'classin' && $user->rights->facture->creer) { - $db->rollback(); - $action = 'create'; - $_GET["origin"] = $_POST["origin"]; - $_GET["originid"] = $_POST["originid"]; - setEventMessages($object->error, $object->errors, 'errors'); + $object->fetch($id); + $object->setProject($_POST['projectid']); } -} -// Add a new line -else if ($action == 'addline' && $user->rights->facture->creer) -{ - $langs->load('errors'); - $error = 0; - - // Set if we used free entry or predefined product - $predef=''; - $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); - $price_ht = GETPOST('price_ht'); - if (GETPOST('prod_entry_mode') == 'free') + else if ($action == 'setmode' && $user->rights->facture->creer) { - $idprod=0; - $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - } - else - { - $idprod=GETPOST('idprod', 'int'); - $tva_tx = ''; - } - - $qty = GETPOST('qty' . $predef); - $remise_percent = GETPOST('remise_percent' . $predef); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key . $predef]); - } - } - - if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { - setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' - { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); - $error ++; - } - if ($qty == '') { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); - $error ++; - } - if ($qty < 0) { - $langs->load("errors"); - setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), 'errors'); - $error ++; - } - if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { - $ret = $object->fetch($id); - if ($ret < 0) { + $object->fetch($id); + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); + if ($result < 0) dol_print_error($db, $object->error); - exit(); + } + + else if ($action == 'setinvoicedate' && $user->rights->facture->creer) + { + $object->fetch($id); + $old_date_lim_reglement = $object->date_lim_reglement; + $date = dol_mktime(12, 0, 0, $_POST['invoicedatemonth'], $_POST['invoicedateday'], $_POST['invoicedateyear']); + if (empty($date)) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id.'&action=editinvoicedate'); + exit; } - $ret = $object->fetch_thirdparty(); + $object->date=$date; + $new_date_lim_reglement = $object->calculate_date_lim_reglement(); + if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement; + if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date; + $result = $object->update($user); + if ($result < 0) dol_print_error($db, $object->error); + } - // Clean parameters - $date_start = dol_mktime(GETPOST('date_start' . $predef . 'hour'), GETPOST('date_start' . $predef . 'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year')); - $date_end = dol_mktime(GETPOST('date_end' . $predef . 'hour'), GETPOST('date_end' . $predef . 'min'), GETPOST('date_end' . $predef . 'sec'), GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year')); - $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT'); + else if ($action == 'setconditions' && $user->rights->facture->creer) + { + $object->fetch($id); + $object->cond_reglement_code = 0; // To clean property + $object->cond_reglement_id = 0; // To clean property + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + if ($result < 0) dol_print_error($db, $object->error); - // Define special_code for special lines - $special_code = 0; - // if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices + $old_date_lim_reglement = $object->date_lim_reglement; + $new_date_lim_reglement = $object->calculate_date_lim_reglement(); + if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement; + if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date; + $result = $object->update($user); + if ($result < 0) dol_print_error($db, $object->error); + } - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - // Ecrase $base_price_type par celui du produit - if (! empty($idprod)) { - $prod = new Product($db); - $prod->fetch($idprod); + else if ($action == 'setpaymentterm' && $user->rights->facture->creer) + { + $object->fetch($id); + $object->date_lim_reglement = dol_mktime(12, 0, 0, $_POST['paymenttermmonth'], $_POST['paymenttermday'], $_POST['paymenttermyear']); + if ($object->date_lim_reglement < $object->date) { + $object->date_lim_reglement = $object->calculate_date_lim_reglement(); + setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), 'warnings'); + } + $result = $object->update($user); + if ($result < 0) + dol_print_error($db, $object->error); + } - $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); + else if ($action == 'setrevenuestamp' && $user->rights->facture->creer) + { + $object->fetch($id); + $object->revenuestamp = GETPOST('revenuestamp'); + $result = $object->update($user); + $object->update_price(1); + if ($result < 0) + dol_print_error($db, $object->error); + } - // Update if prices fields are defined - $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id); - $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id); - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; + // bank account + else if ($action == 'setbankaccount' && $user->rights->facture->creer) + { + $result=$object->setBankAccount(GETPOST('fk_account', 'int')); + } - // We define price for product - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) - { - $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; - $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; - $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; - $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; - if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level]; - if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level]; + else if ($action == 'setremisepercent' && $user->rights->facture->creer) + { + $object->fetch($id); + $result = $object->set_remise($user, $_POST['remise_percent']); + } + + else if ($action == "setabsolutediscount" && $user->rights->facture->creer) + { + // POST[remise_id] ou POST[remise_id_for_payment] + if (! empty($_POST["remise_id"])) { + $ret = $object->fetch($id); + if ($ret > 0) { + $result = $object->insert_discount($_POST["remise_id"]); + if ($result < 0) { + setEventMessage($object->error, 'errors'); } - elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) - { - require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + } else { + dol_print_error($db, $object->error); + } + } + if (! empty($_POST["remise_id_for_payment"])) { + require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php'; + $discount = new DiscountAbsolute($db); + $discount->fetch($_POST["remise_id_for_payment"]); - $prodcustprice = new Productcustomerprice($db); + $result = $discount->link_to_invoice(0, $id); + if ($result < 0) { + setEventMessage($discount->error, 'errors'); + } + } + } - $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + else if ($action == 'set_ref_client' && $user->rights->facture->creer) + { + $object->fetch($id); + $object->set_ref_client($_POST['ref_client']); + } - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); - if ($result) { - if (count($prodcustprice->lines) > 0) { - $pu_ht = price($prodcustprice->lines [0]->price); - $pu_ttc = price($prodcustprice->lines [0]->price_ttc); - $price_base_type = $prodcustprice->lines [0]->price_base_type; - $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; - } - } - } + // Classify to validated + else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider) + { + $idwarehouse = GETPOST('idwarehouse'); - // if price ht is forced (ie: calculated by margin rate and cost price) - if (! empty($price_ht)) { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } + $object->fetch($id); + $object->fetch_thirdparty(); - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - elseif ($tva_tx != $prod->tva_tx) { - if ($price_base_type != 'HT') { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); - } else { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } - } + // Check parameters - $desc = ''; + // Check for mandatory prof id + for($i = 1; $i < 6; $i ++) + { + $idprof_mandatory = 'SOCIETE_IDPROF' . ($i) . '_INVOICE_MANDATORY'; + $idprof = 'idprof' . $i; + if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory)) + { + if (! $error) + $langs->load("errors"); + $error ++; + setEventMessage($langs->trans('ErrorProdIdIsMandatory', $langs->transcountry('ProfId' . $i, $object->thirdparty->country_code)), 'errors'); + } + } + + $qualified_for_stock_change = 0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + $qualified_for_stock_change = $object->hasProductsOrServices(2); + } else { + $qualified_for_stock_change = $object->hasProductsOrServices(1); + } + + // Check for warehouse + if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == - 1) { + $error ++; + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), 'errors'); + $action = ''; + } + } + + if (! $error) + { + $result = $object->validate($user, '', $idwarehouse); + if ($result >= 0) + { // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { $outputlangs = $langs; $newlang = ''; - if (empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if (empty($newlang)) - $newlang = $object->thirdparty->default_lang; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; if (! empty($newlang)) { $outputlangs = new Translate("", $conf); $outputlangs->setDefaultLang($newlang); } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records - $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; - } else { - $desc = $prod->description; + $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) dol_print_error($db,$result); } + } + else + { + if (count($object->errors)) setEventMessage($object->errors, 'errors'); + else setEventMessage($object->error, 'errors'); + } + } + } - $desc = dol_concatdesc($desc, $product_desc); + // Go back to draft status (unvalidate) + else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)) + { + $idwarehouse = GETPOST('idwarehouse'); - // Add custom code and origin country into description - if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { - $tmptxt = '('; - if (! empty($prod->customcode)) - $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; - if (! empty($prod->customcode) && ! empty($prod->country_code)) - $tmptxt .= ' - '; - if (! empty($prod->country_code)) - $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); - $tmptxt .= ')'; - $desc = dol_concatdesc($desc, $tmptxt); - } + $object->fetch($id); + $object->fetch_thirdparty(); - $type = $prod->type; + $qualified_for_stock_change = 0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + $qualified_for_stock_change = $object->hasProductsOrServices(2); } else { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); - $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); - $tva_tx = str_replace('*', '', $tva_tx); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - $desc = $product_desc; - $type = GETPOST('type'); + $qualified_for_stock_change = $object->hasProductsOrServices(1); } - // Margin - $fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); - $buyingprice = price2num(GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); + // Check parameters + if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == - 1) { + $error ++; + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), 'errors'); + $action = ''; + } + } - // Local Taxes - $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty); - $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty); + if (! $error) { + // On verifie si la facture a des paiements + $sql = 'SELECT pf.amount'; + $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture as pf'; + $sql .= ' WHERE pf.fk_facture = ' . $object->id; - $info_bits = 0; - if ($tva_npr) - $info_bits |= 0x01; + $result = $db->query($sql); + if ($result) { + $i = 0; + $num = $db->num_rows($result); - if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { - $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); - setEventMessage($mesg, 'errors'); - } else { - // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $date_start, $date_end, 0, $info_bits, '', $price_base_type, $pu_ttc, $type, - 1, $special_code, '', 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option, $_POST['progress']); + while ($i < $num) { + $objp = $db->fetch_object($result); + $totalpaye += $objp->amount; + $i ++; + } + } else { + dol_print_error($db, ''); + } - if ($result > 0) + $resteapayer = $object->total_ttc - $totalpaye; + + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = $object->getVentilExportCompta(); + + // On verifie si aucun paiement n'a ete effectue + if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) { + $result=$object->set_draft($user, $idwarehouse); + if ($result<0) setEventMessage($object->error,'errors'); + + // Define output language if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { @@ -1377,11 +508,1037 @@ else if ($action == 'addline' && $user->rights->facture->creer) $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); } + } + } + } - unset($_POST['prod_entry_mode']); + // Classify "paid" + else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement) + { + $object->fetch($id); + $result = $object->set_paid($user); + if ($result<0) setEventMessage($object->error,'errors'); + } // Classif "paid partialy" + else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement) + { + $object->fetch($id); + $close_code = $_POST["close_code"]; + $close_note = $_POST["close_note"]; + if ($close_code) { + $result = $object->set_paid($user, $close_code, $close_note); + if ($result<0) setEventMessage($object->error,'errors'); + } else { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors'); + } + } // Classify "abandoned" + else if ($action == 'confirm_canceled' && $confirm == 'yes') { + $object->fetch($id); + $close_code = $_POST["close_code"]; + $close_note = $_POST["close_note"]; + if ($close_code) { + $result = $object->set_canceled($user, $close_code, $close_note); + if ($result<0) setEventMessage($object->error,'errors'); + } else { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors'); + } + } + + // Convertir en reduc + else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer) + { + $object->fetch($id); + $object->fetch_thirdparty(); + //$object->fetch_lines(); // Already done into fetch + + // Check if there is already a discount (protection to avoid duplicate creation when resubmit post) + $discountcheck=new DiscountAbsolute($db); + $result=$discountcheck->fetch(0,$object->id); + + $canconvert=0; + if ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 1 && empty($discountcheck->id)) $canconvert=1; // we can convert deposit into discount if deposit is payed completely and not already converted (see real condition into condition used to show button converttoreduc) + if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) + if ($canconvert) + { + $db->begin(); + + // Boucle sur chaque taux de tva + $i = 0; + foreach ($object->lines as $line) { + $amount_ht [$line->tva_tx] += $line->total_ht; + $amount_tva [$line->tva_tx] += $line->total_tva; + $amount_ttc [$line->tva_tx] += $line->total_ttc; + $i ++; + } + + // Insert one discount by VAT rate category + $discount = new DiscountAbsolute($db); + if ($object->type == Facture::TYPE_CREDIT_NOTE) + $discount->description = '(CREDIT_NOTE)'; + elseif ($object->type == Facture::TYPE_DEPOSIT) + $discount->description = '(DEPOSIT)'; + else { + setEventMessage($langs->trans('CantConvertToReducAnInvoiceOfThisType'),'errors'); + } + $discount->tva_tx = abs($object->total_ttc); + $discount->fk_soc = $object->socid; + $discount->fk_facture_source = $object->id; + + $error = 0; + foreach ($amount_ht as $tva_tx => $xxx) { + $discount->amount_ht = abs($amount_ht [$tva_tx]); + $discount->amount_tva = abs($amount_tva [$tva_tx]); + $discount->amount_ttc = abs($amount_ttc [$tva_tx]); + $discount->tva_tx = abs($tva_tx); + + $result = $discount->create($user); + if ($result < 0) + { + $error++; + break; + } + } + + if (empty($error)) + { + // Classe facture + $result = $object->set_paid($user); + if ($result >= 0) + { + $db->commit(); + } + else + { + setEventMessage($object->error,'errors'); + $db->rollback(); + } + } + else + { + setEventMessage($discount->error,'errors'); + $db->rollback(); + } + } + } + + /* + * Insert new invoice in database + */ + else if ($action == 'add' && $user->rights->facture->creer) + { + if ($socid > 0) $object->socid = GETPOST('socid', 'int'); + + $db->begin(); + + $error = 0; + + // Fill array 'array_options' with data from add form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) $error ++; + + // Replacement invoice + if ($_POST['type'] == Facture::TYPE_REPLACEMENT) + { + $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($dateinvoice)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } + + if (! ($_POST['fac_replacement'] > 0)) { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), 'errors'); + } + + if (! $error) { + // This is a replacement invoice + $result = $object->fetch($_POST['fac_replacement']); + $object->fetch_thirdparty(); + + $object->date = $dateinvoice; + $object->note_public = trim($_POST['note_public']); + $object->note = trim($_POST['note']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = $_POST['cond_reglement_id']; + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->fk_account = GETPOST('fk_account', 'int'); + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; + + // Proprietes particulieres a facture de remplacement + $object->fk_facture_source = $_POST['fac_replacement']; + $object->type = Facture::TYPE_REPLACEMENT; + + $id = $object->createFromCurrent($user); + if ($id <= 0) { + setEventMessage($object->error, 'errors'); + } + } + } + + // Credit note invoice + if ($_POST['type'] == Facture::TYPE_CREDIT_NOTE) + { + if (! ($_POST['fac_avoir'] > 0)) + { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), 'errors'); + } + + $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($dateinvoice)) + { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->trans("Date")), 'errors'); + } + + if (! $error) + { + $object->socid = GETPOST('socid','int'); + $object->number = $_POST['facnumber']; + $object->date = $dateinvoice; + $object->note_public = trim($_POST['note_public']); + $object->note = trim($_POST['note']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = 0; + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->fk_account = GETPOST('fk_account', 'int'); + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; + + // Proprietes particulieres a facture avoir + $object->fk_facture_source = $_POST['fac_avoir']; + $object->type = Facture::TYPE_CREDIT_NOTE; + + $id = $object->create($user); + + if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0) + { + $facture_source = new Facture($db); // fetch origin object + if ($facture_source->fetch($object->fk_facture_source)>0) + { + + foreach($facture_source->lines as $line) + { + $line->fk_facture = $object->id; + + $line->subprice =-$line->subprice; // invert price for object + $line->pa_ht = -$line->pa_ht; + $line->total_ht=-$line->total_ht; + $line->total_tva=-$line->total_tva; + $line->total_ttc=-$line->total_ttc; + $line->total_localtax1=-$line->total_localtax1; + $line->total_localtax2=-$line->total_localtax2; + + $line->insert(); + + $object->lines[] = $line; // insert new line in current object + } + + $object->update_price(1); + } + + } + + if(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int')==1 && $id>0) + { + $facture_source = new Facture($db); // fetch origin object if not previously defined + if ($facture_source->fetch($object->fk_facture_source)>0) + { + $totalpaye = $facture_source->getSommePaiement(); + $totalcreditnotes = $facture_source->getSumCreditNotesUsed(); + $totaldeposits = $facture_source->getSumDepositsUsed(); + $remain_to_pay = abs($facture_source->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits); + + $object->addline($langs->trans('invoiceAvoirLineWithPaymentRestAmount'),$remain_to_pay,1,0,0,0,0,0,'','','TTC'); + } + } + + // Add predefined lines + /* + TODO delete + for($i = 1; $i <= $NBLINES; $i ++) { + if ($_POST['idprod' . $i]) { + $product = new Product($db); + $product->fetch($_POST['idprod' . $i]); + $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']); + $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']); + $result = $object->addline($product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); + } + }*/ + } + } + + // Standard invoice or Deposit invoice created from a Predefined invoice + if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT) && $_POST['fac_rec'] > 0) + { + $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($dateinvoice)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } + + if (! $error) + { + $object->socid = GETPOST('socid','int'); + $object->type = $_POST['type']; + $object->number = $_POST['facnumber']; + $object->date = $dateinvoice; + $object->note_public = trim($_POST['note_public']); + $object->note_private = trim($_POST['note_private']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + + // Source facture + $object->fac_rec = $_POST['fac_rec']; + + $id = $object->create($user); + } + } + + // Standard or deposit or proforma invoice + if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT || $_POST['type'] == Facture::TYPE_PROFORMA || ($_POST['type'] == Facture::TYPE_SITUATION && empty($_POST['situations']))) && $_POST['fac_rec'] <= 0) + { + if (GETPOST('socid', 'int') < 1) + { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); + } + + $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($dateinvoice)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } + + if (! $error) + { + // Si facture standard + $object->socid = GETPOST('socid','int'); + $object->type = GETPOST('type'); + $object->number = $_POST['facnumber']; + $object->date = $dateinvoice; + $object->note_public = trim($_POST['note_public']); + $object->note_private = trim($_POST['note_private']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']); + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->fk_account = GETPOST('fk_account', 'int'); + $object->amount = $_POST['amount']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; + + if (GETPOST('type') == Facture::TYPE_SITUATION) + { + $object->situation_counter = 1; + $object->situation_final = 0; + $object->situation_cycle_ref = $object->newCycle(); + } + + $object->fetch_thirdparty(); + + // If creation from another object of another module (Example: origin=propal, originid=1) + if ($origin && $originid) + { + // Parse element/subelement (ex: project_task) + $element = $subelement = $origin; + if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { + $element = $regs [1]; + $subelement = $regs [2]; + } + + // For compatibility + if ($element == 'order') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; + $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + if ($element == 'inter') { + $element = $subelement = 'ficheinter'; + } + if ($element == 'shipping') { + $element = $subelement = 'expedition'; + } + + $object->origin = $origin; + $object->origin_id = $originid; + + // Possibility to add external linked objects with hooks + $object->linked_objects[$object->origin] = $object->origin_id; + // link with order if it is a shipping invoice + if ($object->origin == 'shipping') + { + require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php'; + $exp = new Expedition($db); + $exp->fetch($object->origin_id); + $exp->fetchObjectLinked(); + if (count($exp->linkedObjectsIds['commande']) > 0) $object->linked_objects['commande'] = $exp->linkedObjectsIds['commande'][0]; + } + + if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) + { + $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + } + + $id = $object->create($user); + + if ($id > 0) + { + // If deposit invoice + if ($_POST['type'] == Facture::TYPE_DEPOSIT) + { + $typeamount = GETPOST('typedeposit', 'alpha'); + $valuedeposit = GETPOST('valuedeposit', 'int'); + + if ($typeamount == 'amount') + { + $amountdeposit = $valuedeposit; + } + else + { + $amountdeposit = 0; + + dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add deposit lines"); + $result = $srcobject->fetch($object->origin_id); + if ($result > 0) + { + $totalamount = 0; + $lines = $srcobject->lines; + $numlines=count($lines); + for ($i=0; $i<$numlines; $i++) + { + $qualified=1; + if (empty($lines[$i]->qty)) $qualified=0; // We discard qty=0, it is an option + if (! empty($lines[$i]->special_code)) $qualified=0; // We discard special_code (frais port, ecotaxe, option, ...) + if ($qualified) $totalamount += $lines[$i]->total_ht; + } + + if ($totalamount != 0) { + $amountdeposit = ($totalamount * $valuedeposit) / 100; + } + } else { + setEventMessage($srcobject->error, 'errors'); + $error ++; + } + } + + $result = $object->addline( + $langs->trans('Deposit'), + $amountdeposit, // subprice + 1, // quantity + $lines[$i]->tva_tx, 0, // localtax1_tx + 0, // localtax2_tx + 0, // fk_product + 0, // remise_percent + 0, // date_start + 0, // date_end + 0, $lines[$i]->info_bits, // info_bits + 0, // info_bits + 'HT', + 0, + 0, // product_type + 1, + $lines[$i]->special_code, + $object->origin, + 0, + 0, + 0, + 0, + $langs->trans('Deposit') + ); + } + else + { + + dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); + $result = $srcobject->fetch($object->origin_id); + if ($result > 0) + { + $lines = $srcobject->lines; + if (empty($lines) && method_exists($srcobject, 'fetch_lines')) + { + $srcobject->fetch_lines(); + $lines = $srcobject->lines; + } + + $fk_parent_line=0; + $num=count($lines); + for ($i=0;$i<$num;$i++) + { + // Don't add lines with qty 0 when coming from a shipment including all order lines + if($srcobject->element == 'shipping' && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS && $lines[$i]->qty == 0) continue; + + $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); + $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); + if ($object->situation_counter == 1) $lines[$i]->situation_percent = 0; + + if ($lines[$i]->subprice < 0) + { + // Negative line, we create a discount line + $discount = new DiscountAbsolute($db); + $discount->fk_soc = $object->socid; + $discount->amount_ht = abs($lines[$i]->total_ht); + $discount->amount_tva = abs($lines[$i]->total_tva); + $discount->amount_ttc = abs($lines[$i]->total_ttc); + $discount->tva_tx = $lines[$i]->tva_tx; + $discount->fk_user = $user->id; + $discount->description = $desc; + $discountid = $discount->create($user); + if ($discountid > 0) { + $result = $object->insert_discount($discountid); // This include link_to_invoice + } else { + setEventMessage($discount->error, 'errors'); + $error ++; + break; + } + } else { + // Positive line + $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0); + + // Date start + $date_start = false; + if ($lines[$i]->date_debut_prevue) + $date_start = $lines[$i]->date_debut_prevue; + if ($lines[$i]->date_debut_reel) + $date_start = $lines[$i]->date_debut_reel; + if ($lines[$i]->date_start) + $date_start = $lines[$i]->date_start; + + // Date end + $date_end = false; + if ($lines[$i]->date_fin_prevue) + $date_end = $lines[$i]->date_fin_prevue; + if ($lines[$i]->date_fin_reel) + $date_end = $lines[$i]->date_fin_reel; + if ($lines[$i]->date_end) + $date_end = $lines[$i]->date_end; + + // Reset fk_parent_line for no child products and special product + if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { + $fk_parent_line = 0; + } + + // Extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) { + $lines[$i]->fetch_optionals($lines[$i]->rowid); + $array_option = $lines[$i]->array_options; + } + + $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $object->origin, $lines[$i]->rowid, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_option, $lines[$i]->situation_percent, $lines[$i]->fk_prev_id); + + if ($result > 0) { + $lineid = $result; + } else { + $lineid = 0; + $error ++; + break; + } + + // Defined the new fk_parent_line + if ($result > 0 && $lines[$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + } + + // Hooks + $parameters = array('objFrom' => $srcobject); + $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if ($reshook < 0) + $error ++; + } else { + setEventMessage($srcobject->error, 'errors'); + $error ++; + } + } + } else { + setEventMessage($object->error, 'errors'); + $error ++; + } + } // If some invoice's lines already known + else { + $id = $object->create($user); + + for($i = 1; $i <= $NBLINES; $i ++) { + if ($_POST['idprod' . $i]) { + $product = new Product($db); + $product->fetch($_POST['idprod' . $i]); + $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']); + $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']); + $result = $object->addline($product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); + } + } + } + } + } + + if (GETPOST('type') == Facture::TYPE_SITUATION && (!empty($_POST['situations']))) + { + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) { + $error++; + $mesg = '
' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '
'; + } + + if (!($_POST['situations'] > 0)) { + $error++; + $mesg = '
' . $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation")) . '
'; + } + + if (!$error) { + $result = $object->fetch($_POST['situations']); + $object->fk_facture_source = $_POST['situations']; + $object->type = Facture::TYPE_SITUATION; + + $object->fetch_thirdparty(); + $object->date = $datefacture; + $object->note_public = trim($_POST['note_public']); + $object->note = trim($_POST['note']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = $_POST['cond_reglement_id']; + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; + + // Proprietes particulieres a facture de remplacement + + $object->situation_counter = $object->situation_counter + 1; + $id = $object->createFromCurrent($user); + if ($id <= 0) $mesg = $object->error; + } + } + + // End of object creation, we show it + if ($id > 0 && ! $error) + { + $db->commit(); + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); + exit(); + } + else + { + $db->rollback(); + $action = 'create'; + $_GET["origin"] = $_POST["origin"]; + $_GET["originid"] = $_POST["originid"]; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + + // Add a new line + else if ($action == 'addline' && $user->rights->facture->creer) + { + $langs->load('errors'); + $error = 0; + + // Set if we used free entry or predefined product + $predef=''; + $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); + $price_ht = GETPOST('price_ht'); + if (GETPOST('prod_entry_mode') == 'free') + { + $idprod=0; + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + } + else + { + $idprod=GETPOST('idprod', 'int'); + $tva_tx = ''; + } + + $qty = GETPOST('qty' . $predef); + $remise_percent = GETPOST('remise_percent' . $predef); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key . $predef]); + } + } + + if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { + setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' + { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); + $error ++; + } + if ($qty == '') { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); + $error ++; + } + if ($qty < 0) { + $langs->load("errors"); + setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), 'errors'); + $error ++; + } + if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { + $ret = $object->fetch($id); + if ($ret < 0) { + dol_print_error($db, $object->error); + exit(); + } + $ret = $object->fetch_thirdparty(); + + // Clean parameters + $date_start = dol_mktime(GETPOST('date_start' . $predef . 'hour'), GETPOST('date_start' . $predef . 'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year')); + $date_end = dol_mktime(GETPOST('date_end' . $predef . 'hour'), GETPOST('date_end' . $predef . 'min'), GETPOST('date_end' . $predef . 'sec'), GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year')); + $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT'); + + // Define special_code for special lines + $special_code = 0; + // if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices + + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + // Ecrase $base_price_type par celui du produit + if (! empty($idprod)) { + $prod = new Product($db); + $prod->fetch($idprod); + + $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); + + // Update if prices fields are defined + $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id); + $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id); + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + + // We define price for product + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) + { + $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; + $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; + if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level]; + if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level]; + } + elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + + $prodcustprice = new Productcustomerprice($db); + + $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result) { + if (count($prodcustprice->lines) > 0) { + $pu_ht = price($prodcustprice->lines [0]->price); + $pu_ttc = price($prodcustprice->lines [0]->price_ttc); + $price_base_type = $prodcustprice->lines [0]->price_base_type; + $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; + } + } + } + + // if price ht is forced (ie: calculated by margin rate and cost price) + if (! empty($price_ht)) { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + elseif ($tva_tx != $prod->tva_tx) { + if ($price_base_type != 'HT') { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); + } else { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + } + + $desc = ''; + + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if (empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; + } else { + $desc = $prod->description; + } + + $desc = dol_concatdesc($desc, $product_desc); + + // Add custom code and origin country into description + if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { + $tmptxt = '('; + if (! empty($prod->customcode)) + $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; + if (! empty($prod->customcode) && ! empty($prod->country_code)) + $tmptxt .= ' - '; + if (! empty($prod->country_code)) + $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); + $tmptxt .= ')'; + $desc = dol_concatdesc($desc, $tmptxt); + } + + $type = $prod->type; + } else { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); + $tva_tx = str_replace('*', '', $tva_tx); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + $desc = $product_desc; + $type = GETPOST('type'); + } + + // Margin + $fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); + $buyingprice = price2num(GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); + + // Local Taxes + $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty); + $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty); + + $info_bits = 0; + if ($tva_npr) + $info_bits |= 0x01; + + if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { + $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); + setEventMessage($mesg, 'errors'); + } else { + // Insert line + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $date_start, $date_end, 0, $info_bits, '', $price_base_type, $pu_ttc, $type, - 1, $special_code, '', 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option, $_POST['progress']); + + if ($result > 0) + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST['prod_entry_mode']); + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); + unset($_POST['np_marginRate']); + unset($_POST['np_markRate']); + unset($_POST['dp_desc']); + unset($_POST['idprod']); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); + + unset($_POST['situations']); + unset($_POST['progress']); + } else { + setEventMessage($object->error, 'errors'); + } + + $action = ''; + } + } + } + + elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel')) + { + if (! $object->fetch($id) > 0) dol_print_error($db); + $object->fetch_thirdparty(); + + // Clean parameters + $date_start = ''; + $date_end = ''; + $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc')); + $pu_ht = GETPOST('price_ht'); + $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + $qty = GETPOST('qty'); + + // Define info_bits + $info_bits = 0; + if (preg_match('/\*/', $vat_rate)) + $info_bits |= 0x01; + + // Define vat_rate + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty); + $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty); + + // Add buying price + $fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : ''); + $buyingprice = price2num(GETPOST('buying_price') ? GETPOST('buying_price') : ''); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + $line = new FactureLigne($db); + $line->fetch(GETPOST('lineid')); + $percent = $line->get_prev_progress(); + + if (GETPOST('progress') < $percent) + { + $mesg = '
' . $langs->trans("CantBeLessThanMinPercent") . '
'; + setEventMessages($mesg, null, 'warnings'); + $error++; + $result = -1; + } + + // Check minimum price + $productid = GETPOST('productid', 'int'); + if (! empty($productid)) + { + $product = new Product($db); + $product->fetch($productid); + + $type = $product->type; + + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) + $price_min = $product->multiprices_min [$object->thirdparty->price_level]; + + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); + + // Check price is not lower than minimum (check is done only for standard or replacement invoices) + if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { + setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); + $error ++; + } + } else { + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + + // Check parameters + if (GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); + $error ++; + } + } + if ($qty < 0) { + $langs->load("errors"); + setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), 'errors'); + $error ++; + } + + // Update line + if (! $error) { + $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $qty, GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option, GETPOST('progress')); + + if ($result >= 0) { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } unset($_POST['qty']); unset($_POST['type']); + unset($_POST['productid']); unset($_POST['remise_percent']); unset($_POST['price_ht']); unset($_POST['price_ttc']); @@ -1393,6 +1550,7 @@ else if ($action == 'addline' && $user->rights->facture->creer) unset($_POST['buying_price']); unset($_POST['np_marginRate']); unset($_POST['np_markRate']); + unset($_POST['dp_desc']); unset($_POST['idprod']); @@ -1414,295 +1572,164 @@ else if ($action == 'addline' && $user->rights->facture->creer) } else { setEventMessage($object->error, 'errors'); } + } + } + else if ($action == 'updatealllines' && $user->rights->facture->creer && $_POST['all_percent'] == $langs->trans('Modifier')) + { + if (!$object->fetch($id) > 0) dol_print_error($db); + if (!is_null(GETPOST('all_progress')) && GETPOST('all_progress') != "") + { + foreach ($object->lines as $line) + { + $percent = $line->get_prev_progress(); + if (GETPOST('all_progress') < $percent) { + $mesg = '
' . $langs->trans("CantBeLessThanMinPercent") . '
'; + $result = -1; + } else + $object->update_percent($line, $_POST['all_progress']); + } + } + } + + else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); // Pour reaffichage de la fiche en cours d'edition + exit(); + } + + // Modify line position (up) + else if ($action == 'up' && $user->rights->facture->creer) { + $object->fetch($id); + $object->fetch_thirdparty(); + $object->line_up($_GET ['rowid']); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); + exit(); + } // Modify line position (down) + else if ($action == 'down' && $user->rights->facture->creer) { + $object->fetch($id); + $object->fetch_thirdparty(); + $object->line_down($_GET ['rowid']); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); + exit(); + } + + // Link invoice to order + if (GETPOST('linkedOrder')) { + $object->fetch($id); + $object->fetch_thirdparty(); + $result = $object->add_object_linked('commande', GETPOST('linkedOrder')); + } + + + /* + * Send mail + */ + + // Actions to send emails + if (empty($id)) $id=$facid; + $actiontypecode='AC_FAC'; + $trigger_name='BILL_SENTBYMAIL'; + $paramname='id'; + $mode='emailfrominvoice'; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + + + /* + * Generate document + */ + if ($action == 'builddoc') // En get ou en post + { + $object->fetch($id); + $object->fetch_thirdparty(); + + // Save last template used to generate document + if (GETPOST('model')) + $object->setDocModel($user, GETPOST('model', 'alpha')); + if (GETPOST('fk_bank')) // this field may come from an external module + $object->fk_bank = GETPOST('fk_bank'); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db, $result); + exit(); + } + } + + // Remove file in doc form + else if ($action == 'remove_file') { + if ($object->fetch($id)) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $object->fetch_thirdparty(); + + $langs->load("other"); + $upload_dir = $conf->facture->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret = dol_delete_file($file, 0, 0, 0, $object); + if ($ret) + setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else + setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); $action = ''; } } -} -elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel')) -{ - if (! $object->fetch($id) > 0) dol_print_error($db); - $object->fetch_thirdparty(); + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; - // Clean parameters - $date_start = ''; - $date_end = ''; - $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description = dol_htmlcleanlastbr(GETPOST('product_desc')); - $pu_ht = GETPOST('price_ht'); - $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - $qty = GETPOST('qty'); + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) + { + if ($action == 'addcontact') + { + $result = $object->fetch($id); - // Define info_bits - $info_bits = 0; - if (preg_match('/\*/', $vat_rate)) - $info_bits |= 0x01; - - // Define vat_rate - $vat_rate = str_replace('*', '', $vat_rate); - $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty); - $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty); - - // Add buying price - $fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : ''); - $buyingprice = price2num(GETPOST('buying_price') ? GETPOST('buying_price') : ''); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key]); - } - } - - $line = new FactureLigne($db); - $line->fetch(GETPOST('lineid')); - $percent = $line->get_prev_progress(); - - if (GETPOST('progress') < $percent) { - $mesg = '
' . $langs->trans("CantBeLessThanMinPercent") . '
'; - setEventMessages($mesg, null, 'warnings'); - $error++; - $result = -1; - } - - // Check minimum price - $productid = GETPOST('productid', 'int'); - if (! empty($productid)) { - $product = new Product($db); - $product->fetch($productid); - - $type = $product->type; - - $price_min = $product->price_min; - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) - $price_min = $product->multiprices_min [$object->thirdparty->price_level]; - - $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); - - // Check price is not lower than minimum (check is done only for standard or replacement invoices) - if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); - $error ++; - } - } else { - $type = GETPOST('type'); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - - // Check parameters - if (GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); - $error ++; - } - } - if ($qty < 0) { - $langs->load("errors"); - setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), 'errors'); - $error ++; - } - - // Update line - if (! $error) { - $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $qty, GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option, GETPOST('progress')); - - if ($result >= 0) { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result > 0 && $id > 0) { + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); } - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['productid']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); - unset($_POST['price_ttc']); - unset($_POST['tva_tx']); - unset($_POST['product_ref']); - unset($_POST['product_label']); - unset($_POST['product_desc']); - unset($_POST['fournprice']); - unset($_POST['buying_price']); - unset($_POST['np_marginRate']); - unset($_POST['np_markRate']); - unset($_POST['situations']); - unset($_POST['progress']); - } else { - setEventMessage($object->error, 'errors'); - } - } -} - -else if ($action == 'updatealllines' && $user->rights->facture->creer && $_POST['all_percent'] == $langs->trans('Modifier')) { - if (!$object->fetch($id) > 0) dol_print_error($db); - if (!is_null(GETPOST('all_progress')) && GETPOST('all_progress') != "") { - foreach ($object->lines as $line) { - $percent = $line->get_prev_progress(); - if (GETPOST('all_progress') < $percent) { - $mesg = '
' . $langs->trans("CantBeLessThanMinPercent") . '
'; - $result = -1; - } else - $object->update_percent($line, $_POST['all_progress']); - } - } -} - -else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) { - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); // Pour reaffichage de la fiche en cours d'edition - exit(); -} - -// Modify line position (up) -else if ($action == 'up' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_up($_GET ['rowid']); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); - exit(); -} // Modify line position (down) -else if ($action == 'down' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_down($_GET ['rowid']); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); - exit(); -} - -// Link invoice to order -if (GETPOST('linkedOrder')) { - $object->fetch($id); - $object->fetch_thirdparty(); - $result = $object->add_object_linked('commande', GETPOST('linkedOrder')); -} - - -/* - * Send mail - */ - -// Actions to send emails -if (empty($id)) $id=$facid; -$actiontypecode='AC_FAC'; -$trigger_name='BILL_SENTBYMAIL'; -$paramname='id'; -$mode='emailfrominvoice'; -include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; - - -/* - * Generate document - */ -if ($action == 'builddoc') // En get ou en post -{ - $object->fetch($id); - $object->fetch_thirdparty(); - - // Save last template used to generate document - if (GETPOST('model')) - $object->setDocModel($user, GETPOST('model', 'alpha')); - if (GETPOST('fk_bank')) // this field may come from an external module - $object->fk_bank = GETPOST('fk_bank'); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db, $result); - exit(); - } -} - -// Remove file in doc form -else if ($action == 'remove_file') { - if ($object->fetch($id)) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - $object->fetch_thirdparty(); - - $langs->load("other"); - $upload_dir = $conf->facture->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) - setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); - else - setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); - $action = ''; - } -} - -include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; - -if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) -{ - if ($action == 'addcontact') - { - $result = $object->fetch($id); - - if ($result > 0 && $id > 0) { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); - } - if ($result >= 0) { header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); exit(); @@ -1717,16 +1744,18 @@ if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture- } // bascule du statut d'un contact - else if ($action == 'swapstatut') { + else if ($action == 'swapstatut') + { if ($object->fetch($id)) { $result = $object->swapContactStatus(GETPOST('ligne')); } else { dol_print_error($db); - } + } } // Efface un contact - else if ($action == 'deletecontact') { + else if ($action == 'deletecontact') + { $object->fetch($id); $result = $object->delete_contact($lineid); @@ -1737,37 +1766,39 @@ if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture- dol_print_error($db); } } -} -if ($action == 'update_extras') { - // Fill array 'array_options' with data from add form - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); - if ($ret < 0) - $error ++; - if (! $error) { - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('invoicedao')); - $parameters = array('id' => $object->id); - $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by - // some hooks - if (empty($reshook)) { - $result = $object->insertExtraFields(); - if ($result < 0) { - $error ++; - } - } else if ($reshook < 0) + if ($action == 'update_extras') + { + // Fill array 'array_options' with data from add form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) $error ++; + + if (! $error) { + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('invoicedao')); + $parameters = array('id' => $object->id); + $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by + // some hooks + if (empty($reshook)) { + $result = $object->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } else if ($reshook < 0) + $error ++; + } + + if ($error) + $action = 'edit_extras'; + } } - - if ($error) - $action = 'edit_extras'; } - /* * View */ @@ -2038,6 +2069,8 @@ if ($action == 'create') if ($socid > 0) { + if (! empty($conf->global->INVOICE_USE_SITUATION)) + { // First situation invoice print ''; print ''; @@ -2060,7 +2093,8 @@ if ($action == 'create') $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceSituationDesc"), 1); print $desc; print '' . "\n"; - + } + // Replacement print ''; print '
'; print ''; - print '     '; + print '     '; print ''; print '
'; @@ -3194,7 +3228,10 @@ if ($action == 'create') print ''; // Situations - if ($object->type == 5 && ($object->situation_counter > 1)) { + if (! empty($conf->global->INVOICE_US_SITUATION)) + { + if ($object->type == 5 && ($object->situation_counter > 1)) + { $prevsits = $object->get_prev_sits(); print ''; print $langs->trans('SituationAmount'); @@ -3236,7 +3273,8 @@ if ($action == 'create') print '' . $langs->trans('Currency' . $conf->currency) . ''; } } - + } + // Amount print '' . $langs->trans('AmountHT') . ''; print '' . price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency) . ''; @@ -3334,6 +3372,13 @@ if ($action == 'create') // Lines $result = $object->getLinesArray(); + print '
+ + + + + '; + if (! empty($conf->use_javascript_ajax) && $object->statut == 0) { include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; } @@ -3341,6 +3386,8 @@ if ($action == 'create') print ''; // Show global modifiers + if (! empty($conf->global->INVOICE_US_SITUATION)) + { if ($object->situation_cycle_ref && $object->statut == 0) { print ''; print ''; @@ -3385,14 +3432,8 @@ if ($action == 'create') print ''; print ''; } - - print ' - - - - - '; - + } + // Show object lines if (! empty($object->lines)) $ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 1); @@ -3465,7 +3506,7 @@ if ($action == 'create') } // Validate - if ($object->statut == 0 && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA|| $object->type == Facture::TYPE_SITUATION) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { + if ($object->statut == 0 && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { if ($user->rights->facture->valider) { print ''; } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 58720101874..0a1f3118c77 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -202,17 +202,6 @@ class Facture extends CommonInvoice if (! $this->cond_reglement_id) $this->cond_reglement_id = 0; if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; $this->brouillon = 1; - if (empty($this->situation_cycle_ref)) { - $this->situation_cycle_ref = 'null'; - } - - if (empty($this->situation_counter)) { - $this->situation_counter = 'null'; - } - - if (empty($this->situation_final)) { - $this->situation_final = '0'; - } dol_syslog(get_class($this)."::create user=".$user->id); @@ -301,12 +290,12 @@ class Facture extends CommonInvoice $sql.= ",".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null"); $sql.= ",".($user->id > 0 ? "'".$user->id."'":"null"); $sql.= ",".($this->fk_project?$this->fk_project:"null"); - $sql.= ','.$this->cond_reglement_id; - $sql.= ",".$this->mode_reglement_id; + $sql.= ", ".$this->cond_reglement_id; + $sql.= ", ".$this->mode_reglement_id; $sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."'"; - $sql.= ", ".$this->situation_cycle_ref; - $sql.= ", ".$this->situation_counter; - $sql.= ", ".$this->situation_final; + $sql.= ", ".($this->situation_cycle_ref?"'".$this->db->escape($this->situation_cycle_ref)."'":"null"); + $sql.= ", ".($this->situation_counter?"'".$this->db->escape($this->situation_counter)."'":"null"); + $sql.= ", ".($this->situation_final?$this->situation_final:0); $sql.=")"; dol_syslog(get_class($this)."::create", LOG_DEBUG); @@ -2027,7 +2016,7 @@ class Facture extends CommonInvoice * @param int $fk_prev_id Previous situation line id reference * @return int <0 if KO, Id of line if OK */ - function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=self::TYPE_STANDARD, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_option=0, $situation_percent=0, $fk_prev_id='') + function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=self::TYPE_STANDARD, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_option=0, $situation_percent=100, $fk_prev_id='') { global $mysoc, $conf, $langs; @@ -2335,11 +2324,10 @@ class Facture extends CommonInvoice } /** - * Update_percent - * + * Update invoice line with percentage + * * @param FactureLigne $line Invoice line - * @param int $percent percent - * + * @param int $percent Percentage * @return void */ function update_percent($line, $percent) @@ -2610,14 +2598,19 @@ class Facture extends CommonInvoice else if ($conf->global->FACTURE_ADDON=='terre') $conf->global->FACTURE_ADDON='mod_facture_terre'; else if ($conf->global->FACTURE_ADDON=='mercure') $conf->global->FACTURE_ADDON='mod_facture_mercure'; + if (! empty($conf->global->FACTURE_ADDON)) + { $mybool=false; $file = $conf->global->FACTURE_ADDON.".php"; $classname = $conf->global->FACTURE_ADDON; // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/facture/"; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/facture/"); + // Load file with numbering class (if found) $mybool|=@include_once $dir.$file; } @@ -2636,7 +2629,6 @@ class Facture extends CommonInvoice $mybool|=@include_once $dir.$file; } } - //print "xx".$mybool.$dir.$file."-".$classname; if (! $mybool) { @@ -2646,7 +2638,7 @@ class Facture extends CommonInvoice $obj = new $classname(); $numref = ""; - $numref = $obj->getNumRef($soc,$this,$mode); + $numref = $obj->getNextValue($soc,$this,$mode); if ($numref != "") { @@ -2654,8 +2646,15 @@ class Facture extends CommonInvoice } else { - //dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error); - return false; + dol_print_error($db,"Facture::getNextNumRef ".$obj->error); + return ""; + } + } + else + { + $langs->load("errors"); + print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete"); + return ""; } } @@ -3455,7 +3454,7 @@ class Facture extends CommonInvoice /** * Checks if the invoice is the first of a cycle * - * @return boolean ($this->situation_counter == 1) + * @return boolean */ function is_first() { @@ -3465,7 +3464,7 @@ class Facture extends CommonInvoice /** * Returns an array containing the previous situations as Facture objects * - * @return array array of prev_sits + * @return mixed -1 if error, array of previous situations */ function get_prev_sits() { diff --git a/htdocs/compta/facture/impayees.php b/htdocs/compta/facture/impayees.php index 0c6b2af84f0..13190ce6e10 100644 --- a/htdocs/compta/facture/impayees.php +++ b/htdocs/compta/facture/impayees.php @@ -553,7 +553,7 @@ if ($resql) print_liste_field_titre($langs->trans("Taxes"),$_SERVER["PHP_SELF"],"f.tva","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Received"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Rest"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Rest"),$_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"fk_statut,paye,am","",$param,'align="right"',$sortfield,$sortorder); if (empty($mode)) { diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index fabf656c895..7432a7d14fd 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -71,185 +71,188 @@ if ($facid > 0) // Initialize technical object to manage hooks of paiements. Note that conf->hooks_modules contains array array $hookmanager->initHooks(array('paiementcard','globalcard')); -$parameters=array('socid'=>$socid); -$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - /* * Actions */ -if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes')) +$parameters=array('socid'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) { - $error = 0; + if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes')) + { + $error = 0; - $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - $paiement_id = 0; - $totalpayment = 0; - $atleastonepaymentnotnull = 0; + $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $paiement_id = 0; + $totalpayment = 0; + $atleastonepaymentnotnull = 0; - // Generate payment array and check if there is payment higher than invoice and payment date before invoice date - $tmpinvoice=new Facture($db); - foreach ($_POST as $key => $value) - { - if (substr($key,0,7) == 'amount_') - { - $cursorfacid = substr($key,7); - $amounts[$cursorfacid] = price2num(trim(GETPOST($key))); - $totalpayment = $totalpayment + $amounts[$cursorfacid]; - if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++; - $result=$tmpinvoice->fetch($cursorfacid); - if ($result <= 0) dol_print_error($db); - $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement()); - if ($amounts[$cursorfacid]) - { - // Check amount - if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid]))) - { - $addwarning=1; - $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPay")).' '.$langs->trans("HelpPaymentHigherThanReminderToPay"); - } - // Check date - if ($datepaye && ($datepaye < $tmpinvoice->date)) - { - $langs->load("errors"); - //$error++; - setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings'); - } - } - - $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => $_POST[$key]); - } - } - - // Check parameters - if (! GETPOST('paiementcode')) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors'); - $error++; - } - - if (! empty($conf->banque->enabled)) - { - // If bank module is on, account is required to enter a payment - if (GETPOST('accountid') <= 0) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); - $error++; - } - } - - if (empty($totalpayment) && empty($atleastonepaymentnotnull)) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors'); - $error++; - } - - if (empty($datepaye)) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors'); - $error++; - } -} - -/* - * Action add_paiement - */ -if ($action == 'add_paiement') -{ - if ($error) - { - $action = 'create'; - } - // Le reste propre a cette action s'affiche en bas de page. -} - -/* - * Action confirm_paiement - */ -if ($action == 'confirm_paiement' && $confirm == 'yes') -{ - $error=0; - - $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - - $db->begin(); - - // Clean parameters amount if payment is for a credit note - if (GETPOST('type') == 2) - { - foreach ($amounts as $key => $value) // How payment is dispatch + // Generate payment array and check if there is payment higher than invoice and payment date before invoice date + $tmpinvoice=new Facture($db); + foreach ($_POST as $key => $value) { - $newvalue = price2num($value,'MT'); - $amounts[$key] = -$newvalue; + if (substr($key,0,7) == 'amount_') + { + $cursorfacid = substr($key,7); + $amounts[$cursorfacid] = price2num(trim(GETPOST($key))); + $totalpayment = $totalpayment + $amounts[$cursorfacid]; + if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++; + $result=$tmpinvoice->fetch($cursorfacid); + if ($result <= 0) dol_print_error($db); + $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement()); + if ($amounts[$cursorfacid]) + { + // Check amount + if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid]))) + { + $addwarning=1; + $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPay")).' '.$langs->trans("HelpPaymentHigherThanReminderToPay"); + } + // Check date + if ($datepaye && ($datepaye < $tmpinvoice->date)) + { + $langs->load("errors"); + //$error++; + setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings'); + } + } + + $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => $_POST[$key]); + } } - } - if (! empty($conf->banque->enabled)) - { - // Si module bank actif, un compte est obligatoire lors de la saisie d'un paiement - if (GETPOST('accountid') <= 0) - { - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); - $error++; - } - } + // Check parameters + if (! GETPOST('paiementcode')) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors'); + $error++; + } - // Creation of payment line - $paiement = new Paiement($db); - $paiement->datepaye = $datepaye; - $paiement->amounts = $amounts; // Array with all payments dispatching - $paiement->paiementid = dol_getIdFromCode($db,$_POST['paiementcode'],'c_paiement'); - $paiement->num_paiement = $_POST['num_paiement']; - $paiement->note = $_POST['comment']; + if (! empty($conf->banque->enabled)) + { + // If bank module is on, account is required to enter a payment + if (GETPOST('accountid') <= 0) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); + $error++; + } + } - if (! $error) - { - $paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices')=='on'?1:0)); - if ($paiement_id < 0) - { - setEventMessage($paiement->error, 'errors'); - $error++; - } - } + if (empty($totalpayment) && empty($atleastonepaymentnotnull)) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors'); + $error++; + } - if (! $error) - { - $label='(CustomerInvoicePayment)'; - if (GETPOST('type') == 2) $label='(CustomerInvoicePaymentBack)'; - $result=$paiement->addPaymentToBank($user,'payment',$label,GETPOST('accountid'),GETPOST('chqemetteur'),GETPOST('chqbank')); - if ($result < 0) - { - setEventMessage($paiement->error, 'errors'); - $error++; - } - } + if (empty($datepaye)) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors'); + $error++; + } + } - if (! $error) - { - $db->commit(); + /* + * Action add_paiement + */ + if ($action == 'add_paiement') + { + if ($error) + { + $action = 'create'; + } + // Le reste propre a cette action s'affiche en bas de page. + } - // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card - $invoiceid=0; - foreach ($paiement->amounts as $key => $amount) - { - $facid = $key; - if (is_numeric($amount) && $amount <> 0) - { - if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment - else $invoiceid=$facid; - } - } - if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture.php?facid='.$invoiceid; - else $loc = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$paiement_id; - header('Location: '.$loc); - exit; - } - else - { - $db->rollback(); - } + /* + * Action confirm_paiement + */ + if ($action == 'confirm_paiement' && $confirm == 'yes') + { + $error=0; + + $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + + $db->begin(); + + // Clean parameters amount if payment is for a credit note + if (GETPOST('type') == 2) + { + foreach ($amounts as $key => $value) // How payment is dispatch + { + $newvalue = price2num($value,'MT'); + $amounts[$key] = -$newvalue; + } + } + + if (! empty($conf->banque->enabled)) + { + // Si module bank actif, un compte est obligatoire lors de la saisie d'un paiement + if (GETPOST('accountid') <= 0) + { + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); + $error++; + } + } + + // Creation of payment line + $paiement = new Paiement($db); + $paiement->datepaye = $datepaye; + $paiement->amounts = $amounts; // Array with all payments dispatching + $paiement->paiementid = dol_getIdFromCode($db,$_POST['paiementcode'],'c_paiement'); + $paiement->num_paiement = $_POST['num_paiement']; + $paiement->note = $_POST['comment']; + + if (! $error) + { + $paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices')=='on'?1:0)); + if ($paiement_id < 0) + { + setEventMessage($paiement->error, 'errors'); + $error++; + } + } + + if (! $error) + { + $label='(CustomerInvoicePayment)'; + if (GETPOST('type') == 2) $label='(CustomerInvoicePaymentBack)'; + $result=$paiement->addPaymentToBank($user,'payment',$label,GETPOST('accountid'),GETPOST('chqemetteur'),GETPOST('chqbank')); + if ($result < 0) + { + setEventMessage($paiement->error, 'errors'); + $error++; + } + } + + if (! $error) + { + $db->commit(); + + // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card + $invoiceid=0; + foreach ($paiement->amounts as $key => $amount) + { + $facid = $key; + if (is_numeric($amount) && $amount <> 0) + { + if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment + else $invoiceid=$facid; + } + } + if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture.php?facid='.$invoiceid; + else $loc = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$paiement_id; + header('Location: '.$loc); + exit; + } + else + { + $db->rollback(); + } + } } diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index e4fa1e05d29..db4c436dfa6 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -736,7 +736,7 @@ class BonPrelevement extends CommonObject function Create($banque=0, $agence=0, $mode='real') { global $conf,$langs; - + dol_syslog(__METHOD__."::Bank=".$banque." Office=".$agence, LOG_DEBUG); require_once (DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"); @@ -782,7 +782,7 @@ class BonPrelevement extends CommonObject //if ($agence) $sql.= " AND sr.code_guichet = '".$conf->global->PRELEVEMENT_CODE_GUICHET."'"; dol_syslog(__METHOD__."::Read invoices, sql=".$sql, LOG_DEBUG); - + $resql = $this->db->query($sql); if ($resql) { @@ -894,24 +894,23 @@ class BonPrelevement extends CommonObject if (!$error) { $ref = substr($year,-2).$month; - + $sql = "SELECT substring(ref from char_length(ref) - 1)"; $sql.= " FROM ".MAIN_DB_PREFIX."prelevement_bons"; $sql.= " WHERE ref LIKE '%".$ref."%'"; $sql.= " AND entity = ".$conf->entity; $sql.= " ORDER BY ref DESC LIMIT 1"; - + dol_syslog(get_class($this)."::Create sql=".$sql, LOG_DEBUG); - dol_syslog(__METHOD__."::Treatments", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $row = $this->db->fetch_row($resql); $ref = "T".$ref.str_pad(dol_substr("00".intval($row[0])+1),2,"0",STR_PAD_LEFT); - + $filebonprev = $ref; - + // Create withdraw receipt in database $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons ("; $sql.= " ref, entity, datec"; @@ -920,18 +919,16 @@ class BonPrelevement extends CommonObject $sql.= ", ".$conf->entity; $sql.= ", '".$this->db->idate($now)."'"; $sql.= ")"; - - dol_syslog(__METHOD__, LOG_DEBUG); + $resql = $this->db->query($sql); - if ($resql) { $prev_id = $this->db->last_insert_id(MAIN_DB_PREFIX."prelevement_bons"); - + $dir=$conf->prelevement->dir_output.'/receipts'; $file=$filebonprev; if (! is_dir($dir)) dol_mkdir($dir); - + $bonprev = new BonPrelevement($this->db, $dir."/".$file); $bonprev->id = $prev_id; } @@ -946,8 +943,6 @@ class BonPrelevement extends CommonObject $error++; dol_syslog(__METHOD__."::Get last withdraw receipt ".$this->db->error(), LOG_ERR); } - - } /* @@ -1011,7 +1006,7 @@ class BonPrelevement extends CommonObject */ dol_syslog(__METHOD__."::Init withdraw receipt for ".count($factures_prev)." invoices", LOG_DEBUG); - + if (count($factures_prev) > 0) { $bonprev->date_echeance = $datetimeprev; @@ -1045,13 +1040,10 @@ class BonPrelevement extends CommonObject $sql.= " WHERE rowid = ".$prev_id; $sql.= " AND entity = ".$conf->entity; - dol_syslog(__METHOD__."::Update total, sql=".$sql, LOG_DEBUG); - $resql=$this->db->query($sql); if (! $resql) { $error++; - dol_syslog("Erreur mise a jour du total - $sql"); dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR); } diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index bbba602fa02..1417047b269 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -211,23 +211,31 @@ class Contrat extends CommonObject global $db, $langs, $conf; $langs->load("contracts"); - $dir = DOL_DOCUMENT_ROOT . "/core/modules/contract"; - - if (empty($conf->global->CONTRACT_ADDON)) + if (!empty($conf->global->CONTRACT_ADDON)) { - $conf->global->CONTRACT_ADDON='mod_contract_serpis'; - } + $mybool = false; - $file = $conf->global->CONTRACT_ADDON.".php"; + $file = $conf->global->CONTRACT_ADDON.".php"; + $classname = $conf->global->CONTRACT_ADDON; - // Chargement de la classe de numerotation - $classname = $conf->global->CONTRACT_ADDON; + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/contract/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } - $result=include_once $dir.'/'.$file; - if ($result) - { $obj = new $classname(); - $numref = ""; $numref = $obj->getNextValue($soc,$this); @@ -237,15 +245,17 @@ class Contrat extends CommonObject } else { + $this->error = $obj->error; dol_print_error($db,get_class($this)."::getNextValue ".$obj->error); return ""; } } else { - print $langs->trans("Error")." ".$langs->trans("Error_CONTRACT_ADDON_NotDefined"); + $langs->load("errors"); + print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete"); return ""; - } + } } /** diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php new file mode 100644 index 00000000000..431ac89a94e --- /dev/null +++ b/htdocs/core/actions_printing.inc.php @@ -0,0 +1,64 @@ + + * Copyright (C) 2014 Frederic France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/actions_printing.inc.php + * \brief Code for actions print_file to print file with calling trigger + */ + + +// $action must be defined +// $db, $user, $conf, $langs must be defined +// Filename to print must be provided into 'file' parameter + +// Print file +if ($action == 'print_file' and $user->rights->printing->read) +{ + $langs->load("printing"); + require_once DOL_DOCUMENT_ROOT . '/core/modules/printing/modules_printing.php'; + $objectprint = new PrintingDriver($db); + $list = $objectprint->listDrivers($db, 10); + if (! empty($list)) { + $errorprint=0; + $printed=0; + foreach ($list as $driver) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $langs->load($driver); + $classname = 'printing_'.$driver; + $printer = new $classname($db); + //print '
'.print_r($printer, true).'
'; + + if (! empty($conf->global->{$printer->active})) { + $subdir=(GETPOST('printer', 'alpha')=='expedition'?'sending':''); + $errorprint = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha'), $subdir); + //if ($errorprint < 0) { + // setEventMessage($interface->errors, 'errors'); + //} + if ($errorprint=='') { + setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file'))).' '.$langs->trans("ViaModule").' '.$printer->name); + $printed++; + } + } + } + if ($printed==0) setEventMessage($langs->trans("NoActivePrintingModuleFound")); + } else { + setEventMessage($langs->trans("NoModuleFound"), 'warning'); + } + $action = ''; +} diff --git a/htdocs/core/actions_printipp.inc.php b/htdocs/core/actions_printipp.inc.php deleted file mode 100644 index 3c18faa813b..00000000000 --- a/htdocs/core/actions_printipp.inc.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * or see http://www.gnu.org/ - */ - -/** - * \file htdocs/core/actions_printipp.inc.php - * \brief Code for actions print_file to print file using ipp - */ - - -// $action must be defined -// $db, $user, $conf, $langs must be defined -// Filename to print must be provided into 'file' parameter - -// Print file -if ($action == 'print_file' and $user->rights->printipp->read) -{ - $langs->load("printipp"); - require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; - $printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); - $result = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha')); - if ($result) - { - setEventMessage($result,'warnings'); - } - else - { - setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file')))); - } - $action = ''; -} diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 49de1529321..80385d34735 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -103,7 +103,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO } else // Id du contact { - $sendto = $thirdparty->contact_get_property($_POST['receiver'],'email'); + $sendto = $thirdparty->contact_get_property((int) $_POST['receiver'],'email'); $sendtoid = $_POST['receiver']; } } @@ -120,7 +120,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO } else // Id du contact { - $sendtocc = $thirdparty->contact_get_property($_POST['receivercc'],'email'); + $sendtocc = $thirdparty->contact_get_property((int) $_POST['receivercc'],'email'); } } diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index fbf5363b753..b7f8e09677f 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -404,7 +404,7 @@ abstract class CommonDocGenerator { global $conf; - return array( + $resarray= array( 'line_fulldesc'=>doc_getlinedesc($line,$outputlangs), 'line_product_ref'=>$line->product_ref, 'line_product_label'=>$line->product_label, @@ -425,6 +425,18 @@ abstract class CommonDocGenerator 'line_date_end'=>$line->date_end, 'line_date_end_rfc'=>dol_print_date($line->date_end,'rfc') ); + + // Retrieve extrafields + $extrafieldkey=$line->element; + $array_key="line"; + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields = new ExtraFields($this->db); + $extralabels = $extrafields->fetch_name_optionals_label($extrafieldkey,true); + $line->fetch_optionals($line->rowid,$extralabels); + + $resarray = $this->fill_substitutionarray_with_extrafields($line,$resarray,$extrafields,$array_key=$array_key,$outputlangs); + + return $resarray; } /** diff --git a/htdocs/core/class/dolprintipp.class.php b/htdocs/core/class/dolprintipp.class.php index b6e09547743..252b742cc9d 100644 --- a/htdocs/core/class/dolprintipp.class.php +++ b/htdocs/core/class/dolprintipp.class.php @@ -28,7 +28,7 @@ class dolprintIPP { var $host; var $port; - var $userid; /* user login */ + var $userid; /* user login */ var $user; var $password; var $error; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 72220f0a4e0..aa1f79cfb11 100755 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2666,7 +2666,7 @@ class Form * * @return string HTML select */ - function load_situation_invoices($selected = '', $socid=null) + function load_situation_invoices($selected = '', $socid = '') { global $langs; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index bea2fa7347e..91bf047f88a 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -273,9 +273,9 @@ class FormFile } $printer=0; - if (in_array($modulepart,array('facture','propal','proposal','order','commande'))) // This feature is implemented only for such elements + if (in_array($modulepart,array('facture','propal','proposal','order','commande','expedition'))) // This feature is implemented only for such elements { - $printer = (!empty($user->rights->printipp->read) && !empty($conf->printipp->enabled))?true:false; + $printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false; } $hookmanager->initHooks(array('formfile')); @@ -604,8 +604,8 @@ class FormFile $out.= '
'; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''."\n"; + $list = $this->getlist_available_printers(); + //$html.= ''; + $var = true; + foreach ($list['available'] as $printer_det) + { + $var=!$var; + $html.= ""; + $html.= ''; + $html.= ''; + $html.= ''; // id to identify printer to use + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + // Defaut + $html.= ''; + $html.= ''."\n"; + } + + return $html; + } + + /** + * Return list of available printers + * + * @return array list of printers + */ + function getlist_available_printers() + { + global $conf,$db; + if ($this->authtoken=='') { + $this->GoogleLogin(); + } + $ret['available'] = $this->get_printer_detail(); + return $ret; + } + + /** + * List of printers + * + * @return array list of printers + */ + function get_printer_detail() + { + // Check if we have auth token + if(empty($this->authtoken)) { + // We don't have auth token so throw exception + throw new Exception("Please first login to Google by calling loginToGoogle function"); + } + // Prepare auth headers with auth token + $authheaders = array("Authorization: GoogleLogin auth=".$this->authtoken, + "GData-Version: 3.0", + ); + // Make Http call to get printers added by user to Google Cloud Print + $responsedata = $this->makeCurl(self::PRINTERS_SEARCH_URL,array(),$authheaders); + $printers = json_decode($responsedata); + // Check if we have printers? + if(is_null($printers)) { + // We dont have printers so return blank array + return array(); + } else { + // We have printers so returns printers as array + return $this->parsePrinters($printers); + } + } + + /** + * Print selected file + * + * @param string $file file + * @param string $module module + * @param string $subdir subdir for file + * @return string '' if OK, Error message if KO + */ + function print_file($file, $module, $subdir='') + { + global $conf, $user, $db; + if ($this->authtoken=='') { + $this->GoogleLogin(); + } + // si $module=commande_fournisseur alors $conf->fournisseur->commande->dir_output + $fileprint=$conf->{$module}->dir_output; + if ($subdir!='') $fileprint.='/'.$subdir; + $fileprint.='/'.$file; + // select printer uri for module order, propal,... + $sql = 'SELECT rowid, printer_id, copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printgcp" AND userid='.$user->id; + $result = $db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj) + { + $printer_id=$obj->printer_id; + } + else + { + if (! empty($conf->global->PRINTING_GCP_DEFAULT)) + { + $printer_id=$conf->global->PRINTING_GCP_DEFAULT; + } + else + { + return 'NoDefaultPrinterDefined'; + } + } + } + + $this->sendPrintToPrinter($printer_id, $file, $fileprint, 'application/pdf'); + } + + /** + * Sends document to the printer + * + * @param string $printerid Printer id returned by Google Cloud Print + * @param string $printjobtitle Job Title + * @param string $filepath File Path to be send to Google Cloud Print + * @param string $contenttype File content type by example application/pdf, image/png + * @return array status array + */ + public function sendPrintToPrinter($printerid,$printjobtitle,$filepath,$contenttype) + { + $errors=0; + // Check auth token + if(empty($this->authtoken)) { + $errors++; + setEventMessage('Please first login to Google', 'warning'); + } + // Check if printer id + if(empty($printerid)) { + $errors++; + setEventMessage('No provided printer ID', 'warning'); + } + // Open the file which needs to be print + $handle = fopen($filepath, "rb"); + if(!$handle) { + $errors++; + setEventMessage('Could not read the file.'); + } + // Read file content + $contents = fread($handle, filesize($filepath)); + fclose($handle); + // Prepare post fields for sending print + $post_fields = array('printerid' => $printerid, + 'title' => $printjobtitle, + 'contentTransferEncoding' => 'base64', + 'content' => base64_encode($contents), // encode file content as base64 + 'contentType' => $contenttype + ); + // Prepare authorization headers + $authheaders = array("Authorization: GoogleLogin auth=" . $this->authtoken); + // Make http call for sending print Job + $response = json_decode($this->makeCurl(self::PRINT_URL,$post_fields,$authheaders)); + // Has document been successfully sent? + if($response->success=="1") { + return array('status' =>true,'errorcode' =>'','errormessage'=>""); + } else { + return array('status' =>false,'errorcode' =>$response->errorCode,'errormessage'=>$response->message); + } + } + + + /** + * Login into Google Account + * + * @return string true or false + */ + function GoogleLogin() + { + global $db, $conf; + // Prepare post fields required for the login + $loginpostfields = array("accountType" => "HOSTED_OR_GOOGLE", + "Email" => $this->login, + "Passwd" => $this->password, + "service" => "cloudprint", + "source" => "GCP" + ); + // Get the Auth token + $loginresponse = $this->makeCurl(self::LOGIN_URL,$loginpostfields); + $token = $this->getAuthToken($loginresponse); + if(! empty($token)&&!is_null($token)) { + $this->authtoken = $token; + $result=dolibarr_set_const($db, 'PRINTGCP_AUTHTOKEN', $token, 'chaine', 0, '', $conf->entity); + return true; + } else { + return false; + } + + } + + /** + * Parse json response and return printers array + * + * @param string $jsonobj Json response object + * @return array return array of printers + */ + private function parsePrinters($jsonobj) + { + $printers = array(); + if (isset($jsonobj->printers)) { + foreach ($jsonobj->printers as $gcpprinter) { + $printers[] = array('id' =>$gcpprinter->id, + 'name' =>$gcpprinter->name, + 'defaultDisplayName' =>$gcpprinter->defaultDisplayName, + 'displayName' =>$gcpprinter->displayName, + 'ownerId' =>$gcpprinter->ownerId, + 'ownerName' =>$gcpprinter->ownerName, + 'connectionStatus' =>$gcpprinter->connectionStatus, + 'status' =>$gcpprinter->status, + 'type' =>$gcpprinter->type + ); + } + } + return $printers; + } + + /** + * Parse data to get auth token + * + * @param string $response response from curl + * @return string token + */ + private function getAuthToken($response) + { + // Search Auth tag + preg_match("/Auth=([a-z0-9_-]+)/i", $response, $matches); + $authtoken = @$matches[1]; + return $authtoken; + } + + /** + * Curl request + * + * @param string $url url to hit + * @param array $postfields array of post fields + * @param array $headers array of http headers + * @return array response from curl + */ + private function makeCurl($url,$postfields=array(),$headers=array()) + { + // Curl Init + $curl = curl_init($url); + // Curl post request + if(! empty($postfields)) { + // As is HTTP post curl request so set post fields + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields); + } + // Curl request headers + if(! empty($headers)) { + // As curl requires header so set headers here + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + } + curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + // Execute the curl and return response + $response = curl_exec($curl); + curl_close($curl); + return $response; + } + + +} diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php new file mode 100644 index 00000000000..c8a19bffa31 --- /dev/null +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -0,0 +1,284 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/printing/printipp.modules.php + * \ingroup mailing + * \brief File to provide printing with PrintIPP + */ + +include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php'; + +/** + * \class mailing_example + * \brief Class to provide printing with PrintIPP + */ +class printing_printipp extends PrintingDriver +{ + var $name='printipp'; + var $desc='PrintIPPDesc'; + var $picto='printer'; + var $active='PRINTING_PRINTIPP'; + var $conf=array(); + var $host; + var $port; + var $userid; /* user login */ + var $user; + var $password; + var $error; + var $db; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf; + + $this->db=$db; + $this->host=$conf->global->PRINTIPP_HOST; + $this->port=$conf->global->PRINTIPP_PORT; + $this->user=$conf->global->PRINTIPP_USER; + $this->password=$conf->global->PRINTIPP_PASSWORD; + $this->conf[] = array('varname'=>'PRINTIPP_HOST', 'required'=>1, 'example'=>'localhost', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTIPP_PORT', 'required'=>1, 'example'=>'631', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTIPP_USER', 'required'=>0, 'example'=>'', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTIPP_PASSWORD', 'required'=>0, 'example'=>'', 'type'=>'password'); + } + + /** + * Print selected file + * + * @param string $file file + * @param string $module module + * @param string $subdir subdirectory of document like for expedition subdir is sendings + * + * @return string '' if OK, Error message if KO + */ + function print_file($file, $module, $subdir='') + { + global $conf, $user, $db; + + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setJobName($file,true); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + + // select printer uri for module order, propal,... + $sql = 'SELECT rowid,printer_id,copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printipp" AND userid='.$user->id; + $result = $db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj) + { + $ipp->setPrinterURI($obj->printer_id); + } + else + { + if (! empty($conf->global->PRINTIPP_URI_DEFAULT)) + { + $ipp->setPrinterURI($conf->global->PRINTIPP_URI_DEFAULT); + } + else + { + return 'NoDefaultPrinterDefined'; + } + } + } + + // Set number of copy + $ipp->setCopies($obj->copy); + $fileprint=$conf->{$module}->dir_output; + if ($subdir!='') $fileprint.='/'.$subdir; + $fileprint.='/'.$file; + $ipp->setData($fileprint); + $ipp->printJob(); + + return ''; + } + + /** + * Return list of available printers + * + * @return string html list of printers + */ + function listAvailablePrinters() + { + global $bc, $conf, $langs; + $var=true; + + $html = ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + //$html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= "\n"; + $list = $this->getlist_available_printers(); + $var = true; + foreach ($list as $value) + { + $var=!$var; + $printer_det = $this->get_printer_detail($value); + $html.= ""; + $html.= ''; + //$html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + //$html.= ''; + $html.= ''; + $html.= ''; + // Defaut + $html.= ''; + $html.= ''."\n"; + } + + return $html; + } + + /** + * Return list of available printers + * + * @return array list of printers + */ + function getlist_available_printers() + { + global $conf,$db; + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + $ipp->getPrinters(); + return $ipp->available_printers; + } + + /** + * Get printer detail + * + * @param string $uri URI + * @return array List of attributes + */ + function get_printer_detail($uri) + { + global $conf,$db; + + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + $ipp->setPrinterURI($uri); + $ipp->getPrinterAttributes(); + return $ipp->printer_attributes; + } + + /** + * List jobs print + * + * @param string $module module + * + * @return void + */ + function list_jobs($module) + { + global $conf, $db, $bc; + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + // select printer uri for module order, propal,... + $sql = 'SELECT rowid,printer_uri,printer_name FROM '.MAIN_DB_PREFIX.'printer_ipp WHERE module="'.$module.'"'; + $result = $this->db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj) + { + $ipp->setPrinterURI($obj->printer_uri); + } + else + { + // All printers + $ipp->setPrinterURI("ipp://localhost:631/printers/"); + } + } + // Getting Jobs + $ipp->getJobs(false,0,'completed',false); + print '
'; if ($delallowed) { - $out.= 'trans("Delete"), 'delete.png').''; @@ -614,9 +614,9 @@ class FormFile if ($printer) { //$out.= ''; - $out.= ' '.img_picto($langs->trans("Print"),'printer.png').''; + $out.= ' '.img_picto($langs->trans("PrintFile", $relativepath),'printer.png').''; } if ($morepicto) { diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php index 30f5960e0ce..0f0f715922e 100644 --- a/htdocs/core/class/menubase.class.php +++ b/htdocs/core/class/menubase.class.php @@ -152,7 +152,7 @@ class Menubase $sql.= " '".$this->fk_menu."',"; $sql.= " ".($this->fk_mainmenu?"'".$this->fk_mainmenu."'":"null").","; $sql.= " ".($this->fk_leftmenu?"'".$this->fk_leftmenu."'":"null").","; - $sql.= " '".$this->position."',"; + $sql.= " '".(int) $this->position."',"; $sql.= " '".$this->db->escape($this->url)."',"; $sql.= " '".$this->db->escape($this->target)."',"; $sql.= " '".$this->db->escape($this->titre)."',"; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index bd195e27eab..f8a43030dbc 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2456,19 +2456,22 @@ function dol_print_error($db='',$error='') if ($_SERVER['DOCUMENT_ROOT']) // Mode web { $out.=$langs->trans("DolibarrHasDetectedError").".
\n"; - if (! empty($conf->global->MAIN_FEATURES_LEVEL)) - $out.="You use an experimental level of features, so please do NOT report any bugs, anywhere, until going back to MAIN_FEATURES_LEVEL = 0.
\n"; + if (! empty($conf->global->MAIN_FEATURES_LEVEL)) $out.="You use an experimental level of features, so please do NOT report any bugs, anywhere, until going back to MAIN_FEATURES_LEVEL = 0.
\n"; $out.=$langs->trans("InformationToHelpDiagnose").":
\n"; - $out.="".$langs->trans("Date").": ".dol_print_date(time(),'dayhourlog')."
\n";; - $out.="".$langs->trans("Dolibarr").": ".DOL_VERSION."
\n";; - if (isset($conf->global->MAIN_FEATURES_LEVEL)) $out.="".$langs->trans("LevelOfFeature").": ".$conf->global->MAIN_FEATURES_LEVEL."
\n";; + $out.="".$langs->trans("Date").": ".dol_print_date(time(),'dayhourlog')."
\n"; + $out.="".$langs->trans("Dolibarr").": ".DOL_VERSION."
\n"; + if (isset($conf->global->MAIN_FEATURES_LEVEL)) $out.="".$langs->trans("LevelOfFeature").": ".$conf->global->MAIN_FEATURES_LEVEL."
\n"; if (function_exists("phpversion")) { $out.="".$langs->trans("PHP").": ".phpversion()."
\n"; - //phpinfo(); // This is to show location of php.ini file } $out.="".$langs->trans("Server").": ".$_SERVER["SERVER_SOFTWARE"]."
\n"; + if (function_exists("php_uname")) + { + $out.="".$langs->trans("OS").": ".php_uname()."
\n"; + } + $out.="".$langs->trans("UserAgent").": ".$_SERVER["HTTP_USER_AGENT"]."
\n"; $out.="
\n"; $out.="".$langs->trans("RequestedUrl").": ".dol_htmlentities($_SERVER["REQUEST_URI"],ENT_COMPAT,'UTF-8')."
\n"; $out.="".$langs->trans("Referer").": ".(isset($_SERVER["HTTP_REFERER"])?dol_htmlentities($_SERVER["HTTP_REFERER"],ENT_COMPAT,'UTF-8'):'')."
\n"; diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index aa3a1e11a46..aac29ad5256 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -49,7 +49,7 @@ * @param int $type 0/1=Product/service * @param Societe $seller Thirdparty seller (we need $seller->country_id property). Provided only if seller is the supplier, otherwise $seller will be $mysoc. * @param array $localtaxes_array Array with localtaxes info (loaded by getLocalTaxesFromRate function). - * @param float $progress Situation invoices progress + * @param float $progress Situation invoices progress (value from 0 to 100, 100 by default) * @return result[ 0=total_ht, * 1=total_vat, * 2=total_ttc, @@ -97,6 +97,8 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt if ($uselocaltax1_rate < 0) $uselocaltax1_rate=$seller->localtax1_assuj; if ($uselocaltax2_rate < 0) $uselocaltax2_rate=$seller->localtax2_assuj; + dol_syslog('Price.lib::calcul_price_total qty='.$qty.' pu='.$pu.' remise_percent_ligne='.$remise_percent_ligne.' txtva='.$txtva.' uselocaltax1_rate='.$uselocaltax1_rate.' uselocaltax2_rate='.$uselocaltax2_rate.' remise_percent_global='.$remise_percent_global.' price_base_type='.$ice_base_type.' type='.$type.' progress='.$progress); + // Now we search localtaxes information ourself (rates and types). $localtax1_type=0; $localtax2_type=0; diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 69dabf04219..e78e24c316a 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -344,7 +344,8 @@ abstract class DolibarrModules /** - * Gives the translated module name if translation exists in admin.lang or the default module name. + * Gives the translated module name if translation exists in admin.lang or into language files of module. + * Otherwise return the module key name. * * @return string Translated module name */ @@ -359,9 +360,16 @@ abstract class DolibarrModules return $langs->trans("Module".$this->numero."Name"); } else - { - // If module name translation using it's unique id does not exists, we take its name - return $this->name; + { + // If module name translation using it's unique id does not exists, we take use its name to find translation + if (is_array($this->langfiles)) + { + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); + } + } + return $langs->trans($this->name); } } @@ -382,9 +390,16 @@ abstract class DolibarrModules return $langs->trans("Module".$this->numero."Desc"); } else - { - // If module description translation using it's unique id does not exists, we take its description - return $this->description; + { + // If module description translation using it's unique id does not exists, we take use its name to find translation + if (is_array($this->langfiles)) + { + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); + } + } + return $langs->trans($this->description); } } @@ -868,6 +883,8 @@ abstract class DolibarrModules $err=0; + if (empty($this->const)) return 0; + foreach ($this->const as $key => $value) { $name = $this->const[$key][0]; @@ -935,6 +952,8 @@ abstract class DolibarrModules $err=0; + if (empty($this->const)) return 0; + foreach ($this->const as $key => $value) { $name = $this->const[$key][0]; diff --git a/htdocs/core/modules/modDeplacement.class.php b/htdocs/core/modules/modDeplacement.class.php index 75d3ab328c8..c536553ac4b 100644 --- a/htdocs/core/modules/modDeplacement.class.php +++ b/htdocs/core/modules/modDeplacement.class.php @@ -95,17 +95,17 @@ class modDeplacement extends DolibarrModules $this->rights[3][3] = 0; $this->rights[3][4] = 'supprimer'; - $this->rights[3][0] = 174; - $this->rights[3][1] = 'Lire toutes les notes de frais'; - $this->rights[3][2] = 'd'; - $this->rights[3][3] = 0; - $this->rights[3][4] = 'readall'; + $this->rights[4][0] = 174; + $this->rights[4][1] = 'Lire toutes les notes de frais'; + $this->rights[4][2] = 'd'; + $this->rights[4][3] = 0; + $this->rights[4][4] = 'readall'; - $this->rights[6][0] = 178; - $this->rights[6][1] = 'Exporter les notes de frais et deplacements'; - $this->rights[6][2] = 'd'; - $this->rights[6][3] = 0; - $this->rights[6][4] = 'export'; + $this->rights[5][0] = 178; + $this->rights[5][1] = 'Exporter les notes de frais et deplacements'; + $this->rights[5][2] = 'd'; + $this->rights[5][3] = 0; + $this->rights[5][4] = 'export'; // Exports $r=0; diff --git a/htdocs/core/modules/modPrintIPP.class.php b/htdocs/core/modules/modPrinting.class.php similarity index 59% rename from htdocs/core/modules/modPrintIPP.class.php rename to htdocs/core/modules/modPrinting.class.php index 3cdcd6cdfa6..f578c463d43 100644 --- a/htdocs/core/modules/modPrintIPP.class.php +++ b/htdocs/core/modules/modPrinting.class.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2014 Laurent Destailleur + * Copyright (C) 2014 Frederic France * * 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 @@ -15,42 +16,41 @@ * along with this program. If not, see . */ -/** \defgroup printipp Module printipp - * \brief Module pour imprimer via CUPS +/** \defgroup printing Module printing + * \brief Module for activation of printing icon */ /** - * \file htdocs/core/modules/modPrintIPP.class.php - * \ingroup printipp - * \brief Fichier de description et activation du module OSCommerce2 + * \file htdocs/core/modules/modPrinting.class.php + * \ingroup printing + * \brief Fichier de description et activation du module Printing */ -include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php"); +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * \class modPrintIPP - * \brief Classe de description et activation du module PrintIPP + * \class modPrinting + * \brief Classe de description et activation du module Printing */ -class modPrintIPP extends DolibarrModules +class modPrinting extends DolibarrModules { - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ + /** + * Constructor + * + * @param DoliDB $db Database handler + */ function __construct($db) { $this->db = $db ; - $this->numero = 54000; + $this->numero = 112000; // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' // It is used to group modules in module setup page $this->family = "other"; // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); - $this->description = "Print via Cups IPP Printer."; + $this->description = "Enable Printing System."; $this->version = 'dolibarr'; // 'development' or 'experimental' or 'dolibarr' or version $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) @@ -64,16 +64,15 @@ class modPrintIPP extends DolibarrModules $this->dirs = array(); // Config pages - $this->config_page_url = array("printipp.php@printipp"); + $this->config_page_url = array("printing.php@printing"); // Dependances - $this->hidden = (! empty($_SERVER["WINDIR"])); $this->depends = array(); $this->requiredby = array(); - $this->phpmin = array(5,1); // Minimum version of PHP required by module - $this->need_dolibarr_version = array(3,7,-2); // Minimum version of Dolibarr required by module + $this->phpmin = array(5,1); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(3,7,-2); // Minimum version of Dolibarr required by module $this->conflictwith = array(); - $this->langfiles = array("printipp"); + $this->langfiles = array("printing"); // Constantes $this->const = array(); @@ -83,7 +82,7 @@ class modPrintIPP extends DolibarrModules // Permissions $this->rights = array(); - $this->rights_class = 'printipp'; + $this->rights_class = 'printing'; $r=0; // $this->rights[$r][0] Id permission (unique tous modules confondus) @@ -94,8 +93,8 @@ class modPrintIPP extends DolibarrModules // $this->rights[$r][5] Niveau 2 pour nommer permission dans code $r++; - $this->rights[$r][0] = 54001; - $this->rights[$r][1] = 'Printer'; + $this->rights[$r][0] = 112001; + $this->rights[$r][1] = 'Printing'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 1; $this->rights[$r][4] = 'read'; @@ -106,16 +105,16 @@ class modPrintIPP extends DolibarrModules // This is to declare the Top Menu entry: $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools', // Put 0 if this is a top menu - 'type'=>'left', // This is a Top menu entry - 'titre'=>'Printer', - 'mainmenu'=>'printer', - 'url'=>'/printipp/index.php', - 'langs'=>'printipp', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'type'=>'left', // This is a Top menu entry + 'titre'=>'Printing', + 'mainmenu'=>'printing', + 'url'=>'/printing/index.php', + 'langs'=>'printing', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>300, - 'enabled'=>'$conf->printipp->enabled && $leftmenu==\'modulesadmintools\'', - 'perms'=>'$user->rights->printipp->read', // Use 'perms'=>'1' if you want your menu with no permission rules + 'enabled'=>'$conf->printing->enabled && $leftmenu==\'modulesadmintools\'', + 'perms'=>'$user->rights->printing->read', // Use 'perms'=>'1' if you want your menu with no permission rules 'target'=>'', - 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both + 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both $r++; @@ -123,13 +122,13 @@ class modPrintIPP extends DolibarrModules } /** - * Function called when module is enabled. - * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. - * It also creates data directories - * - * @param string $options Options when enabling module ('', 'noboxes') - * @return int 1 if OK, 0 if KO - */ + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ function init($options='') { $sql = array(); @@ -137,15 +136,15 @@ class modPrintIPP extends DolibarrModules return $this->_init($sql, $options); } - /** - * Function called when module is disabled. - * Remove from database constants, boxes and permissions from Dolibarr database. - * Data directories are not deleted - * - * @param string $options Options when enabling module ('', 'noboxes') - * @return int 1 if OK, 0 if KO - */ - function remove($options='') + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function remove($options='') { $sql = array(); diff --git a/htdocs/printipp/admin/index.html b/htdocs/core/modules/printing/index.html similarity index 100% rename from htdocs/printipp/admin/index.html rename to htdocs/core/modules/printing/index.html diff --git a/htdocs/core/modules/printing/modules_printing.php b/htdocs/core/modules/printing/modules_printing.php new file mode 100644 index 00000000000..3b53711f58c --- /dev/null +++ b/htdocs/core/modules/printing/modules_printing.php @@ -0,0 +1,86 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/mailings/modules_printing.php + * \ingroup printing + * \brief File with parent class of printing modules + */ +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + +/** + * Parent class of emailing target selectors modules + */ +class PrintingDriver +{ + var $db; + var $error; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } + + /** + * Return list of printing driver + * + * @param DoliDB $db Database handler + * @param string $maxfilenamelength Max length of value to show + * @return array List of drivers + */ + static function listDrivers($db,$maxfilenamelength=0) + { + global $conf; + + $type='printing'; + $liste=array(); + + $moduledir=DOL_DOCUMENT_ROOT."/core/modules/printing/"; + $tmpfiles=dol_dir_list($moduledir,'all',0,'\modules.php','','name',SORT_ASC,0); + foreach($tmpfiles as $record) { + $list[$record['fullname']]=str_replace('.modules.php', '',$record['name']); + } + + return $list; + } + + /** + * Return description of Printing Module + * + * @return string Return translation of key PrintingModuleDescXXX where XXX is module name, or $this->desc if not exists + */ + function getDesc() + { + global $langs; + $langs->load("printing"); + $transstring="PrintingModuleDesc".$this->name; + if ($langs->trans($transstring) != $transstring) return $langs->trans($transstring); + else return $this->desc; + } + +} + diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php new file mode 100644 index 00000000000..2d4cb8a2c98 --- /dev/null +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -0,0 +1,355 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/printing/printgcp.modules.php + * \ingroup printing + * \brief File to provide printing with Google Cloud Print + */ + +include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php'; + +/** + * \class mailing_example + * \brief Class to provide printing with Google Cloud Print + */ +class printing_printgcp extends PrintingDriver +{ + var $name = 'printgcp'; + var $desc = 'PrintGCPDesc'; + var $picto = 'printer'; + var $active = 'PRINTING_PRINTGCP'; + var $conf = array(); + var $login = ''; + var $password = ''; + var $authtoken = ''; + var $db; + + const LOGIN_URL = 'https://www.google.com/accounts/ClientLogin'; + const PRINTERS_SEARCH_URL = 'https://www.google.com/cloudprint/interface/search'; + const PRINT_URL = 'https://www.google.com/cloudprint/interface/submit'; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf; + + $this->db = $db; + $this->login = $conf->global->PRINTGCP_LOGIN; + $this->password = $conf->global->PRINTGCP_PASSWORD; + $this->authtoken = $conf->global->PRINTGCP_AUTHTOKEN; + $this->conf[] = array('varname'=>'PRINTGCP_LOGIN', 'required'=>1, 'example'=>'user@gmail.com', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTGCP_PASSWORD', 'required'=>1, 'example'=>'', 'type'=>'password'); + } + + /** + * Return list of available printers + * + * @return string html list of printers + */ + function listAvailablePrinters() + { + global $bc, $conf, $langs; + $langs->load('printgcp'); + $var=true; + + $html = '
'.$langs->trans('GCP_Name').''.$langs->trans('GCP_displayName').''.$langs->trans('GCP_Id').''.$langs->trans('GCP_OwnerName').''.$langs->trans('GCP_State').''.$langs->trans('GCP_connectionStatus').''.$langs->trans('GCP_Type').''.$langs->trans("Select").'
'.print_r($list,true).'
'.$printer_det['name'].''.$printer_det['displayName'].''.$printer_det['id'].''.$printer_det['ownerName'].''.$printer_det['status'].''.$langs->trans('STATE_'.$printer_det['connectionStatus']).''.$langs->trans('TYPE_'.$printer_det['type']).''; + if ($conf->global->PRINTING_GCP_DEFAULT == $printer_det['id']) + { + $html.= img_picto($langs->trans("Default"),'on'); + } + else + $html.= ''.img_picto($langs->trans("Disabled"),'off').''; + $html.= '
'.$langs->trans('IPP_Uri').''.$langs->trans('IPP_Name').''.$langs->trans('IPP_State').''.$langs->trans('IPP_State_reason').''.$langs->trans('IPP_State_reason1').''.$langs->trans('IPP_BW').''.$langs->trans('IPP_Color').''.$langs->trans('IPP_Device').''.$langs->trans('IPP_Media').''.$langs->trans('IPP_Supported').''.$langs->trans("Select").'
'.$value.'
'.print_r($printer_det,true).'
'.$printer_det->printer_name->_value0.''.$langs->trans('STATE_IPP_'.$printer_det->printer_state->_value0).''.$langs->trans('STATE_IPP_'.$printer_det->printer_state_reasons->_value0).''.(! empty($printer_det->printer_state_reasons->_value1)?$langs->trans('STATE_IPP_'.$printer_det->printer_state_reasons->_value1):'').''.$langs->trans('IPP_COLOR_'.$printer_det->printer_type->_value2).''.$langs->trans('IPP_COLOR_'.$printer_det->printer_type->_value3).''.$printer_det->device_uri->_value0.''.$printer_det->media_default->_value0.''.$langs->trans('MEDIA_IPP_'.$printer_det->media_type_supported->_value1).''; + if ($conf->global->PRINTIPP_URI_DEFAULT == $value) + { + $html.= img_picto($langs->trans("Default"),'on'); + } + else + $html.= ''.img_picto($langs->trans("Disabled"),'off').''; + $html.= '
'; + print ''; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print "\n"; + $jobs = $ipp->jobs_attributes; + $var = True; + //print '
'.print_r($jobs,true).'
'; + foreach ($jobs as $value ) + { + $var=!$var; + print ""; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + print "
IdOwnerPrinterFileStatusCancel
'.$value->job_id->_value0.''.$value->job_originating_user_name->_value0.''.$value->printer_uri->_value0.''.$value->job_name->_value0.''.$value->job_state->_value0.''.$value->job_uri->_value0.'
"; + } + +} diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php index eca0da0f9a5..15bef66bf8f 100644 --- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php +++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php @@ -125,7 +125,8 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices return 0; } - $numFinal=get_next_value($db,$mask,'facture_fourn','ref','',$objsoc->code_fournisseur,$object->datef); + //Supplier invoices take invoice date instead of creation date for the mask + $numFinal=get_next_value($db,$mask,'facture_fourn','ref','',$objsoc->code_fournisseur,$object->date); return $numFinal; } diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index 4c3ac6b6928..34d201c9144 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -353,16 +353,20 @@ if (($action=="create") || ($action=="edit")) print ""; print $langs->trans('CronEvery').""; print "unitfrequency=="60"){ + if($object->unitfrequency=="60") + { $input .= ' checked="checked" />'; } else{ diff --git a/htdocs/custom/.gitignore b/htdocs/custom/.gitignore index ed069fdfd81..89ebd12182c 100644 --- a/htdocs/custom/.gitignore +++ b/htdocs/custom/.gitignore @@ -1,4 +1,4 @@ -/a* -/b* -/c* -/d* +/* +!.gitignore +!README.md +!index.html \ No newline at end of file diff --git a/htdocs/printipp/lib/index.html b/htdocs/custom/index.html similarity index 100% rename from htdocs/printipp/lib/index.html rename to htdocs/custom/index.html diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 7ccd24f871b..c93ec795dec 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -108,477 +108,313 @@ $parameters=array(); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if ($action == 'add') +if (empty($reshook)) { - $error=0; - - $db->begin(); - - $object->note = GETPOST('note','alpha'); - $object->origin = $origin; - $object->origin_id = $origin_id; - $object->weight = GETPOST('weight','int')==''?"NULL":GETPOST('weight','int'); - $object->sizeH = GETPOST('sizeH','int')==''?"NULL":GETPOST('sizeH','int'); - $object->sizeW = GETPOST('sizeW','int')==''?"NULL":GETPOST('sizeW','int'); - $object->sizeS = GETPOST('sizeS','int')==''?"NULL":GETPOST('sizeS','int'); - $object->size_units = GETPOST('size_units','int'); - $object->weight_units = GETPOST('weight_units','int'); - - $date_delivery = dol_mktime(GETPOST('date_deliveryhour','int'), GETPOST('date_deliverymin','int'), 0, GETPOST('date_deliverymonth','int'), GETPOST('date_deliveryday','int'), GETPOST('date_deliveryyear','int')); - - // On va boucler sur chaque ligne du document d'origine pour completer objet expedition - // avec info diverses + qte a livrer - $classname = ucfirst($object->origin); - $objectsrc = new $classname($db); - $objectsrc->fetch($object->origin_id); - - $object->socid = $objectsrc->socid; - $object->ref_customer = $objectsrc->ref_client; - $object->date_delivery = $date_delivery; // Date delivery planed - $object->fk_delivery_address = $objectsrc->fk_delivery_address; - $object->shipping_method_id = GETPOST('shipping_method_id','int'); - $object->tracking_number = GETPOST('tracking_number','alpha'); - $object->ref_int = GETPOST('ref_int','alpha'); - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); - - $num=count($objectsrc->lines); - $totalqty=0; - for ($i = 0; $i < $num; $i++) - { - $qty = "qtyl".$i; - $j=0; - $sub_qty=array(); - $subtotalqty=0; - $idl="idl".$i; - $batch="batchl".$i."_0"; - if (isset($_POST[$batch])) { - //shipment line with batch-enable product - $qty .= '_'.$j; - while (isset($_POST[$batch])) { - $sub_qty[$j]['q']=GETPOST($qty,'int'); - $sub_qty[$j]['id_batch']=GETPOST($batch,'int'); - $subtotalqty+=$sub_qty[$j]['q']; - $j++; - $batch="batchl".$i."_".$j; - $qty = "qtyl".$i.'_'.$j; - - } - $batch_line[$i]['detail']=$sub_qty; - $batch_line[$i]['qty']=$subtotalqty; - $batch_line[$i]['ix_l']=GETPOST($idl,'int'); - $totalqty+=$subtotalqty; - } else { - //Standard product - if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int'); - } - } - - if ($totalqty > 0) - { - //var_dump($_POST);exit; - for ($i = 0; $i < $num; $i++) - { - $qty = "qtyl".$i; - if (! isset($batch_line[$i])) { - if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS)) - { - $ent = "entl".$i; - $idl = "idl".$i; - $entrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):GETPOST('entrepot_id','int'); - if ($entrepot_id < 0) $entrepot_id=''; - - $ret=$object->addline($entrepot_id,GETPOST($idl,'int'),GETPOST($qty,'int')); - if ($ret < 0) - { - $mesg='
'.$object->error.'
'; - $error++; - } - } - } else { - if ($batch_line[$i]['qty']>0) { - $ret=$object->addline_batch($batch_line[$i]); - if ($ret < 0) - { - $mesg='
'.$object->error.'
'; - $error++; - } - } - } - } - - if (! $error) - { - $ret=$object->create($user); - if ($ret <= 0) - { - $mesg='
'.$object->error.'
'; - $error++; - } - } - } - else - { - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Qty")).'
'; - $error++; - } - - if (! $error) - { - $db->commit(); - header("Location: card.php?id=".$object->id); - exit; - } - else - { - $db->rollback(); - $_GET["commande_id"]=GETPOST('commande_id','int'); - $action='create'; - } -} - -/* - * Build a receiving receipt - */ -else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer) -{ - $result = $object->create_delivery($user); - if ($result > 0) - { - header("Location: ".DOL_URL_ROOT.'/livraison/card.php?id='.$result); - exit; - } - else - { - $mesg=$object->error; - } -} - -else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->expedition->valider) -{ - $object->fetch_thirdparty(); - - $result = $object->valid($user); - - if ($result < 0) - { - $langs->load("errors"); - setEventMessage($langs->trans($object->error),'errors'); - } - else - { - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records - - $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result < 0) dol_print_error($db,$result); - } - } -} - -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer) -{ - $result = $object->delete(); - if ($result > 0) - { - header("Location: ".DOL_URL_ROOT.'/expedition/index.php'); - exit; - } - else + if ($action == 'add') { - $langs->load("errors"); - setEventMessage($langs->trans($object->error),'errors'); - } -} + $error=0; -else if ($action == 'reopen' && $user->rights->expedition->valider) -{ - $result = $object->setStatut(0); - if ($result < 0) - { - $mesg = $object->error; - } -} + $db->begin(); -else if ($action == 'setdate_livraison' && $user->rights->expedition->creer) -{ - //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; - $datedelivery=dol_mktime(GETPOST('liv_hour','int'), GETPOST('liv_min','int'), 0, GETPOST('liv_month','int'), GETPOST('liv_day','int'), GETPOST('liv_year','int')); + $object->note = GETPOST('note','alpha'); + $object->origin = $origin; + $object->origin_id = $origin_id; + $object->weight = GETPOST('weight','int')==''?"NULL":GETPOST('weight','int'); + $object->sizeH = GETPOST('sizeH','int')==''?"NULL":GETPOST('sizeH','int'); + $object->sizeW = GETPOST('sizeW','int')==''?"NULL":GETPOST('sizeW','int'); + $object->sizeS = GETPOST('sizeS','int')==''?"NULL":GETPOST('sizeS','int'); + $object->size_units = GETPOST('size_units','int'); + $object->weight_units = GETPOST('weight_units','int'); - $object->fetch($id); - $result=$object->set_date_livraison($user,$datedelivery); - if ($result < 0) - { - $mesg='
'.$object->error.'
'; - } -} + $date_delivery = dol_mktime(GETPOST('date_deliveryhour','int'), GETPOST('date_deliverymin','int'), 0, GETPOST('date_deliverymonth','int'), GETPOST('date_deliveryday','int'), GETPOST('date_deliveryyear','int')); -// Action update description of emailing -else if ($action == 'settrackingnumber' || $action == 'settrackingurl' -|| $action == 'settrueWeight' -|| $action == 'settrueWidth' -|| $action == 'settrueHeight' -|| $action == 'settrueDepth' -|| $action == 'setshipping_method_id') -{ - $error=0; + // On va boucler sur chaque ligne du document d'origine pour completer objet expedition + // avec info diverses + qte a livrer + $classname = ucfirst($object->origin); + $objectsrc = new $classname($db); + $objectsrc->fetch($object->origin_id); - if ($action == 'settrackingnumber') $object->tracking_number = trim(GETPOST('trackingnumber','alpha')); - if ($action == 'settrackingurl') $object->tracking_url = trim(GETPOST('trackingurl','int')); - if ($action == 'settrueWeight') { - $object->trueWeight = trim(GETPOST('trueWeight','int')); - $object->weight_units = GETPOST('weight_units','int'); - } - if ($action == 'settrueWidth') $object->trueWidth = trim(GETPOST('trueWidth','int')); - if ($action == 'settrueHeight'){ - $object->trueHeight = trim(GETPOST('trueHeight','int')); - $object->size_units = GETPOST('size_units','int'); + $object->socid = $objectsrc->socid; + $object->ref_customer = $objectsrc->ref_client; + $object->date_delivery = $date_delivery; // Date delivery planed + $object->fk_delivery_address = $objectsrc->fk_delivery_address; + $object->shipping_method_id = GETPOST('shipping_method_id','int'); + $object->tracking_number = GETPOST('tracking_number','alpha'); + $object->ref_int = GETPOST('ref_int','alpha'); + $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public'); + + $num=count($objectsrc->lines); + $totalqty=0; + for ($i = 0; $i < $num; $i++) + { + $qty = "qtyl".$i; + $j=0; + $sub_qty=array(); + $subtotalqty=0; + $idl="idl".$i; + $batch="batchl".$i."_0"; + if (isset($_POST[$batch])) { + //shipment line with batch-enable product + $qty .= '_'.$j; + while (isset($_POST[$batch])) { + $sub_qty[$j]['q']=GETPOST($qty,'int'); + $sub_qty[$j]['id_batch']=GETPOST($batch,'int'); + $subtotalqty+=$sub_qty[$j]['q']; + $j++; + $batch="batchl".$i."_".$j; + $qty = "qtyl".$i.'_'.$j; + + } + $batch_line[$i]['detail']=$sub_qty; + $batch_line[$i]['qty']=$subtotalqty; + $batch_line[$i]['ix_l']=GETPOST($idl,'int'); + $totalqty+=$subtotalqty; + } else { + //Standard product + if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int'); + } + } + + if ($totalqty > 0) + { + //var_dump($_POST);exit; + for ($i = 0; $i < $num; $i++) + { + $qty = "qtyl".$i; + if (! isset($batch_line[$i])) { + if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS)) + { + $ent = "entl".$i; + $idl = "idl".$i; + $entrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):GETPOST('entrepot_id','int'); + if ($entrepot_id < 0) $entrepot_id=''; + + $ret=$object->addline($entrepot_id,GETPOST($idl,'int'),GETPOST($qty,'int')); + if ($ret < 0) + { + $mesg='
'.$object->error.'
'; + $error++; + } + } + } else { + if ($batch_line[$i]['qty']>0) { + $ret=$object->addline_batch($batch_line[$i]); + if ($ret < 0) + { + $mesg='
'.$object->error.'
'; + $error++; + } + } + } + } + + if (! $error) + { + $ret=$object->create($user); + if ($ret <= 0) + { + $mesg='
'.$object->error.'
'; + $error++; + } + } + } + else + { + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Qty")).'
'; + $error++; + } + + if (! $error) + { + $db->commit(); + header("Location: card.php?id=".$object->id); + exit; + } + else + { + $db->rollback(); + $_GET["commande_id"]=GETPOST('commande_id','int'); + $action='create'; + } } - if ($action == 'settrueDepth') $object->trueDepth = trim(GETPOST('trueDepth','int')); - if ($action == 'setshipping_method_id') $object->shipping_method_id = trim(GETPOST('shipping_method_id','int')); - if (! $error) - { - if ($object->update($user) >= 0) - { - header("Location: card.php?id=".$object->id); - exit; - } - setEventMessage($object->error,'errors'); - } + /* + * Build a receiving receipt + */ + else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer) + { + $result = $object->create_delivery($user); + if ($result > 0) + { + header("Location: ".DOL_URL_ROOT.'/livraison/card.php?id='.$result); + exit; + } + else + { + $mesg=$object->error; + } + } - $action=""; -} + else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->expedition->valider) + { + $object->fetch_thirdparty(); -// Build document -else if ($action == 'builddoc') // En get ou en post -{ + $result = $object->valid($user); - // Save last template used to generate document - if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); + if ($result < 0) + { + $langs->load("errors"); + setEventMessage($langs->trans($object->error),'errors'); + } + else + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$shipment->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - $result = $object->generateDocument($object->modelpdf, $outputlangs); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } -} + $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) dol_print_error($db,$result); + } + } + } -// Delete file in doc form -elseif ($action == 'remove_file') -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer) + { + $result = $object->delete(); + if ($result > 0) + { + header("Location: ".DOL_URL_ROOT.'/expedition/index.php'); + exit; + } + else + { + $langs->load("errors"); + setEventMessage($langs->trans($object->error),'errors'); + } + } - $upload_dir = $conf->expedition->dir_output . "/sending"; - $file = $upload_dir . '/' . GETPOST('file'); - $ret=dol_delete_file($file,0,0,0,$object); - if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); - else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); -} + else if ($action == 'reopen' && $user->rights->expedition->valider) + { + $result = $object->setStatut(0); + if ($result < 0) + { + $mesg = $object->error; + } + } -/* - * Add file in email form -*/ -if (GETPOST('addfile','alpha')) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + else if ($action == 'setdate_livraison' && $user->rights->expedition->creer) + { + //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; + $datedelivery=dol_mktime(GETPOST('liv_hour','int'), GETPOST('liv_min','int'), 0, GETPOST('liv_month','int'), GETPOST('liv_day','int'), GETPOST('liv_year','int')); - // Set tmp user directory TODO Use a dedicated directory for temp mails files - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; + $object->fetch($id); + $result=$object->set_date_livraison($user,$datedelivery); + if ($result < 0) + { + $mesg='
'.$object->error.'
'; + } + } - dol_add_file_process($upload_dir_tmp,0,0); - $action ='presend'; -} + // Action update description of emailing + else if ($action == 'settrackingnumber' || $action == 'settrackingurl' + || $action == 'settrueWeight' + || $action == 'settrueWidth' + || $action == 'settrueHeight' + || $action == 'settrueDepth' + || $action == 'setshipping_method_id') + { + $error=0; -/* - * Remove file in email form -*/ -if (GETPOST('removedfile','alpha')) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + if ($action == 'settrackingnumber') $object->tracking_number = trim(GETPOST('trackingnumber','alpha')); + if ($action == 'settrackingurl') $object->tracking_url = trim(GETPOST('trackingurl','int')); + if ($action == 'settrueWeight') { + $object->trueWeight = trim(GETPOST('trueWeight','int')); + $object->weight_units = GETPOST('weight_units','int'); + } + if ($action == 'settrueWidth') $object->trueWidth = trim(GETPOST('trueWidth','int')); + if ($action == 'settrueHeight'){ + $object->trueHeight = trim(GETPOST('trueHeight','int')); + $object->size_units = GETPOST('size_units','int'); + } + if ($action == 'settrueDepth') $object->trueDepth = trim(GETPOST('trueDepth','int')); + if ($action == 'setshipping_method_id') $object->shipping_method_id = trim(GETPOST('shipping_method_id','int')); - // Set tmp user directory - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; + if (! $error) + { + if ($object->update($user) >= 0) + { + header("Location: card.php?id=".$object->id); + exit; + } + setEventMessage($object->error,'errors'); + } - // TODO Delete only files that was uploaded from email form - dol_remove_file_process(GETPOST('removedfile','int'),0); - $action ='presend'; -} + $action=""; + } -/* - * Send mail -*/ -if ($action == 'send' && ! GETPOST('addfile','alpha') && ! GETPOST('removedfile','alpha') && ! GETPOST('cancel','alpha')) -{ - $langs->load('mails'); + // Build document + else if ($action == 'builddoc') // En get ou en post + { + // Save last template used to generate document + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); -// $ref = dol_sanitizeFileName($object->ref); -// $file = $conf->expedition->dir_output . '/sending/' . $ref . '/' . $ref . '.pdf'; + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$shipment->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result = $object->generateDocument($object->modelpdf, $outputlangs); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + } -// if (is_readable($file)) -// { - if (GETPOST('sendto','alpha')) - { - // Le destinataire a ete fourni via le champ libre - $sendto = GETPOST('sendto','alpha'); - $sendtoid = 0; - } - elseif (GETPOST('receiver','alpha') != '-1') - { - // Recipient was provided from combo list - if (GETPOST('receiver','alpha') == 'thirdparty') // Id of third party - { - $sendto = $object->client->email; - $sendtoid = 0; - } - else // Id du contact - { - $sendto = $object->client->contact_get_property(GETPOST('receiver','alpha'),'email'); - $sendtoid = GETPOST('receiver','alpha'); - } - } + // Delete file in doc form + elseif ($action == 'remove_file') + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - if (dol_strlen($sendto)) - { - $langs->load("commercial"); + $upload_dir = $conf->expedition->dir_output . "/sending"; + $file = $upload_dir . '/' . GETPOST('file'); + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + } - $from = GETPOST('fromname','alpha') . ' <' . GETPOST('frommail','alpha') .'>'; - $replyto = GETPOST('replytoname','alpha'). ' <' . GETPOST('replytomail','alpha').'>'; - $message = GETPOST('message'); - $sendtocc = GETPOST('sendtocc','alpha'); - $deliveryreceipt = GETPOST('deliveryreceipt','alpha'); + elseif ($action == 'classifybilled') + { + $object->fetch($id); + $object->set_billed(); + } - if ($action == 'send') - { - if (dol_strlen(GETPOST('subject','alpha'))) $subject=GETPOST('subject','alpha'); - else $subject = $langs->transnoentities('Shipping').' '.$object->ref; - $actiontypecode='AC_SHIP'; - $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; - if ($message) - { - if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); - $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); - $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); - $actionmsg = dol_concatdesc($actionmsg, $message); - } - $actionmsg2=$langs->transnoentities('Action'.$actiontypecode); - } + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; - // Create form object - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); + // Actions to send emails + if (empty($id)) $id=$facid; + $actiontypecode='AC_SHIP'; + $trigger_name='SHIPPING_SENTBYMAIL'; + $paramname='id'; + $mode='emailfromshipment'; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; - $attachedfiles=$formmail->get_attached_files(); - $filepath = $attachedfiles['paths']; - $filename = $attachedfiles['names']; - $mimetype = $attachedfiles['mimes']; - - // Send mail - require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); - if ($mailfile->error) - { - $mesg='
'.$mailfile->error.'
'; - } - else - { - $result=$mailfile->sendfile(); - if ($result) - { - $error=0; - - // Initialisation donnees - $object->sendtoid = $sendtoid; - $object->actiontypecode = $actiontypecode; - $object->actionmsg = $actionmsg; - $object->actionmsg2 = $actionmsg2; - $object->fk_element = $object->id; - $object->elementtype = $object->element; - - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($db); - $result=$interface->run_triggers('SHIPPING_SENTBYMAIL',$object,$user,$langs,$conf); - if ($result < 0) { - $error++; $object->errors=$interface->errors; - } - // Fin appel triggers - - if ($error) - { - dol_print_error($db); - } - else - { - // Redirect here - // This avoid sending mail twice if going out and then back to page - $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); - setEventMessage($mesg); - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; - } - } - else - { - $langs->load("other"); - $mesg='
'; - if ($mailfile->error) - { - $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); - $mesg.='
'.$mailfile->error; - } - else - { - $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; - } - $mesg.='
'; - } - } - } - else - { - $langs->load("other"); - $mesg='
'.$langs->trans('ErrorMailRecipientIsEmpty').' !
'; - $action='presend'; - dol_syslog('Recipient email is empty'); - } -/* } - else - { - $langs->load("errors"); - $mesg='
'.$langs->trans('ErrorCantReadFile',$file).'
'; - dol_syslog('Failed to read file: '.$file); - }*/ -} - -else if ($action == 'classifybilled') -{ - $object->fetch($id); - $object->set_billed(); } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 46f2cbc70fe..74d5251a191 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -121,21 +121,30 @@ class Expedition extends CommonObject global $db, $langs, $conf; $langs->load("sendings"); - $dir = DOL_DOCUMENT_ROOT . "/core/modules/expedition"; - - if (empty($conf->global->EXPEDITION_ADDON_NUMBER)) + if (!empty($conf->global->EXPEDITION_ADDON_NUMBER)) { - $conf->global->EXPEDITION_ADDON_NUMBER='mod_expedition_safor'; - } + $mybool = false; - $file = $conf->global->EXPEDITION_ADDON_NUMBER.".php"; + $file = $conf->global->EXPEDITION_ADDON_NUMBER.".php"; + $classname = $conf->global->EXPEDITION_ADDON_NUMBER; - // Chargement de la classe de numerotation - $classname = $conf->global->EXPEDITION_ADDON_NUMBER; + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/expedition/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } - $result=include_once $dir.'/'.$file; - if ($result) - { $obj = new $classname(); $numref = ""; $numref = $obj->getNextValue($soc,$this); @@ -149,12 +158,12 @@ class Expedition extends CommonObject dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error); return ""; } - } - else - { - print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined"); - return ""; - } + } + else + { + print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined"); + return ""; + } } /** diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index b7887c25278..0f91e976da8 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -574,25 +574,33 @@ class Fichinter extends CommonObject global $conf, $db, $langs; $langs->load("interventions"); - $dir = DOL_DOCUMENT_ROOT . "/core/modules/fichinter/"; - if (! empty($conf->global->FICHEINTER_ADDON)) { - $file = $conf->global->FICHEINTER_ADDON.".php"; - $classname = $conf->global->FICHEINTER_ADDON; - if (! file_exists($dir.$file)) - { - $file='mod_'.$file; - $classname='mod_'.$classname; + $mybool = false; + + $file = "mod_".$conf->global->FICHEINTER_ADDON.".php"; + $classname = "mod_".$conf->global->FICHEINTER_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/fichinter/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; } - // Chargement de la classe de numerotation - require_once $dir.$file; + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } $obj = new $classname(); - $numref = ""; - $numref = $obj->getNumRef($soc,$this); + $numref = $obj->getNextValue($soc,$this); if ( $numref != "") { @@ -606,6 +614,7 @@ class Fichinter extends CommonObject } else { + $langs->load("errors"); print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined"); return ""; } diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 0447bd0a758..205d1a89ea6 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -41,6 +41,7 @@ $langs->load('companies'); $langs->load('commercial'); $action = GETPOST('action'); +$cancelbutton = GETPOST('cancel'); // Security check $id = (GETPOST('socid','int') ? GETPOST('socid','int') : GETPOST('id','int')); @@ -60,10 +61,14 @@ $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if ($action == 'setsupplieraccountancycode') +if (empty($reshook)) { - $cancelbutton = GETPOST('cancel'); - if (! $cancelbutton) + if ($cancelbutton) + { + $action = ""; + } + + if ($action == 'setsupplieraccountancycode') { $result=$object->fetch($id); $object->code_compta_fournisseur=$_POST["supplieraccountancycode"]; @@ -73,21 +78,20 @@ if ($action == 'setsupplieraccountancycode') $mesg=join(',',$object->errors); } } - $action=""; -} -// conditions de reglement -if ($action == 'setconditions' && $user->rights->societe->creer) -{ - $object->fetch($id); - $result=$object->setPaymentTerms(GETPOST('cond_reglement_supplier_id','int')); - if ($result < 0) dol_print_error($db,$object->error); -} -// mode de reglement -if ($action == 'setmode' && $user->rights->societe->creer) -{ - $object->fetch($id); - $result=$object->setPaymentMethods(GETPOST('mode_reglement_supplier_id','int')); - if ($result < 0) dol_print_error($db,$object->error); + // conditions de reglement + if ($action == 'setconditions' && $user->rights->societe->creer) + { + $object->fetch($id); + $result=$object->setPaymentTerms(GETPOST('cond_reglement_supplier_id','int')); + if ($result < 0) dol_print_error($db,$object->error); + } + // mode de reglement + if ($action == 'setmode' && $user->rights->societe->creer) + { + $object->fetch($id); + $result=$object->setPaymentMethods(GETPOST('mode_reglement_supplier_id','int')); + if ($result < 0) dol_print_error($db,$object->error); + } } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index b8c14f2879e..77f131b912b 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -557,44 +557,48 @@ class CommandeFournisseur extends CommonOrder global $db, $langs, $conf; $langs->load("orders"); - $dir = DOL_DOCUMENT_ROOT .'/core/modules/supplier_order/'; - if (! empty($conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER)) { + $mybool = false; + $file = $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER.'.php'; + $classname=$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER; - if (is_readable($dir.'/'.$file)) + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/supplier_order/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) { - // Definition du nom de modele de numerotation de commande fournisseur - $modName=$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER; - require_once $dir.'/'.$file; + dol_print_error('',"Failed to include file ".$file); + return ''; + } - // Recuperation de la nouvelle reference - $objMod = new $modName($this->db); + $obj = new $classname(); + $numref = $obj->getNextValue($soc,$this); - $numref = ""; - $numref = $objMod->commande_get_num($soc,$this); - - if ( $numref != "") - { - return $numref; - } - else - { - dol_print_error($db, get_class($this)."::getNextNumRef ".$obj->error); - return -1; - } + if ( $numref != "") + { + return $numref; } else - { - print $langs->trans("Error")." ".$langs->trans("Error_FailedToLoad_COMMANDE_SUPPLIER_ADDON_File",$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER); - return -2; + { + $this->error = $obj->error; + dol_print_error($db, get_class($this)."::getNextNumRef ".$obj->error); + return -1; } } else - { - print $langs->trans("Error")." ".$langs->trans("Error_COMMANDE_SUPPLIER_ADDON_NotDefined"); - return -3; + { + $this->error = "Error_COMMANDE_SUPPLIER_ADDON_NotDefined"; + return -2; } } diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index b931b566a61..7370bc3769a 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1514,10 +1514,14 @@ class FactureFournisseur extends CommonInvoice $file = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER.".php"; $classname = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER; + // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/supplier_invoice/"; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/supplier_invoice/"); + // Load file with numbering class (if found) $mybool|=@include_once $dir.$file; } diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index b90bd275e4c..57696363289 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -479,14 +479,16 @@ else if ($action == 'confirm_deleteproductline' && $confirm == 'yes' && $user->r $result = $object->deleteline(GETPOST('lineid')); if ($result >= 0) { - $outputlangs = $langs; - if (GETPOST('lang_id')) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang(GETPOST('lang_id')); - } if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } $ret=$object->fetch($object->id); // Reload to get new records $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } @@ -571,6 +573,14 @@ else if ($action == 'confirm_approve' && $confirm == 'yes' && $user->rights->fou if ($result > 0) { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id); diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index afd914546a6..0864a0bc2a5 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -66,169 +66,172 @@ if ($user->societe_id > 0) // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $hookmanager->initHooks(array('paymentsupplier')); -$parameters=array('socid'=>$socid); -$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); /* * Actions */ -if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes')) +$parameters=array('socid'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) { - $error = 0; + if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes')) + { + $error = 0; - $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - $paiement_id = 0; - $totalpayment = 0; - $atleastonepaymentnotnull = 0; + $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $paiement_id = 0; + $totalpayment = 0; + $atleastonepaymentnotnull = 0; - // Generate payment array and check if there is payment higher than invoice and payment date before invoice date - $tmpinvoice=new FactureFournisseur($db); - foreach ($_POST as $key => $value) - { - if (substr($key,0,7) == 'amount_') - { - $cursorfacid = substr($key,7); - $amounts[$cursorfacid] = price2num(trim(GETPOST($key))); - $totalpayment = $totalpayment + $amounts[$cursorfacid]; - if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++; - $result=$tmpinvoice->fetch($cursorfacid); - if ($result <= 0) dol_print_error($db); - $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement()); - if ($amounts[$cursorfacid]) - { - // Check amount - if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid]))) + // Generate payment array and check if there is payment higher than invoice and payment date before invoice date + $tmpinvoice=new FactureFournisseur($db); + foreach ($_POST as $key => $value) + { + if (substr($key,0,7) == 'amount_') + { + $cursorfacid = substr($key,7); + $amounts[$cursorfacid] = price2num(trim(GETPOST($key))); + $totalpayment = $totalpayment + $amounts[$cursorfacid]; + if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++; + $result=$tmpinvoice->fetch($cursorfacid); + if ($result <= 0) dol_print_error($db); + $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement()); + if ($amounts[$cursorfacid]) { - $addwarning=1; - $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPaySupplier")).' '.$langs->trans("HelpPaymentHigherThanReminderToPaySupplier"); + // Check amount + if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid]))) + { + $addwarning=1; + $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPaySupplier")).' '.$langs->trans("HelpPaymentHigherThanReminderToPaySupplier"); + } + // Check date + if ($datepaye && ($datepaye < $tmpinvoice->date)) + { + $langs->load("errors"); + //$error++; + setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings'); + } } - // Check date - if ($datepaye && ($datepaye < $tmpinvoice->date)) + + $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => $_POST[$key]); + } + } + + // Check parameters + if ($_POST['paiementid'] <= 0) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors'); + $error++; + } + + if (! empty($conf->banque->enabled)) + { + // If bank module is on, account is required to enter a payment + if (GETPOST('accountid') <= 0) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); + $error++; + } + } + + if (empty($totalpayment) && empty($atleastonepaymentnotnull)) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors'); + $error++; + } + + if (empty($datepaye)) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors'); + $error++; + } + } + + /* + * Action add_paiement + */ + if ($action == 'add_paiement') + { + if ($error) + { + $action = 'create'; + } + // Le reste propre a cette action s'affiche en bas de page. + } + + + /* + * Action confirm_paiement + */ + if ($action == 'confirm_paiement' && $confirm == 'yes') + { + $error=0; + + $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + + if (! $error) + { + $db->begin(); + + // Creation de la ligne paiement + $paiement = new PaiementFourn($db); + $paiement->datepaye = $datepaye; + $paiement->amounts = $amounts; // Array of amounts + $paiement->paiementid = $_POST['paiementid']; + $paiement->num_paiement = $_POST['num_paiement']; + $paiement->note = $_POST['comment']; + if (! $error) + { + $paiement_id = $paiement->create($user,(GETPOST('closepaidinvoices')=='on'?1:0)); + if ($paiement_id < 0) { - $langs->load("errors"); - //$error++; - setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings'); + setEventMessage($paiement->error, 'errors'); + $error++; } - } + } - $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => $_POST[$key]); - } - } + if (! $error) + { + $result=$paiement->addPaymentToBank($user,'payment_supplier','(SupplierInvoicePayment)',$_POST['accountid'],'',''); + if ($result < 0) + { + setEventMessage($paiement->error, 'errors'); + $error++; + } + } - // Check parameters - if ($_POST['paiementid'] <= 0) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors'); - $error++; - } + if (! $error) + { + $db->commit(); - if (! empty($conf->banque->enabled)) - { - // If bank module is on, account is required to enter a payment - if (GETPOST('accountid') <= 0) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); - $error++; - } - } - - if (empty($totalpayment) && empty($atleastonepaymentnotnull)) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors'); - $error++; - } - - if (empty($datepaye)) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors'); - $error++; - } + // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card + $invoiceid=0; + foreach ($paiement->amounts as $key => $amount) + { + $facid = $key; + if (is_numeric($amount) && $amount <> 0) + { + if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment + else $invoiceid=$facid; + } + } + if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$invoiceid; + else $loc = DOL_URL_ROOT.'/fourn/paiement/card.php?id='.$paiement_id; + header('Location: '.$loc); + exit; + } + else + { + $db->rollback(); + } + } + } } -/* - * Action add_paiement - */ -if ($action == 'add_paiement') -{ - if ($error) - { - $action = 'create'; - } - // Le reste propre a cette action s'affiche en bas de page. -} - - -/* - * Action confirm_paiement - */ -if ($action == 'confirm_paiement' && $confirm == 'yes') -{ - $error=0; - - $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - - if (! $error) - { - $db->begin(); - - // Creation de la ligne paiement - $paiement = new PaiementFourn($db); - $paiement->datepaye = $datepaye; - $paiement->amounts = $amounts; // Array of amounts - $paiement->paiementid = $_POST['paiementid']; - $paiement->num_paiement = $_POST['num_paiement']; - $paiement->note = $_POST['comment']; - if (! $error) - { - $paiement_id = $paiement->create($user,(GETPOST('closepaidinvoices')=='on'?1:0)); - if ($paiement_id < 0) - { - setEventMessage($paiement->error, 'errors'); - $error++; - } - } - - if (! $error) - { - $result=$paiement->addPaymentToBank($user,'payment_supplier','(SupplierInvoicePayment)',$_POST['accountid'],'',''); - if ($result < 0) - { - setEventMessage($paiement->error, 'errors'); - $error++; - } - } - - if (! $error) - { - $db->commit(); - - // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card - $invoiceid=0; - foreach ($paiement->amounts as $key => $amount) - { - $facid = $key; - if (is_numeric($amount) && $amount <> 0) - { - if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment - else $invoiceid=$facid; - } - } - if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$invoiceid; - else $loc = DOL_URL_ROOT.'/fourn/paiement/card.php?id='.$paiement_id; - header('Location: '.$loc); - exit; - } - else - { - $db->rollback(); - } - } -} - - /* * View @@ -458,7 +461,7 @@ if (empty($action)) $search_paymenttype=GETPOST('search_paymenttype'); $search_amount=GETPOST('search_amount'); $search_company=GETPOST('search_company'); - + if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers { $search_ref=""; @@ -596,7 +599,7 @@ if (empty($action)) print ''; print $invoicesupplierstatic->getNomUrl(1); print '';*/ - + print ' '; print ''; $i++; diff --git a/htdocs/includes/printipp/BasicIPP.php b/htdocs/includes/printipp/BasicIPP.php index 3869c75bc06..1cc7851fab2 100644 --- a/htdocs/includes/printipp/BasicIPP.php +++ b/htdocs/includes/printipp/BasicIPP.php @@ -1,6 +1,6 @@ errno = $errno; - } - public function getErrorFormatted() - { - $return = sprintf("[ipp]: %s -- " . _(" file %s, line %s"), - $this->getMessage() , $this->getFile() , $this->getLine()); - return $return; - } - public function getErrno() - { - return $this->errno; - } + protected $errno; + + public function __construct($msg, $errno = null) + { + parent::__construct($msg); + $this->errno = $errno; + } + + public function getErrorFormatted() + { + $return = sprintf("[ipp]: %s -- " . _(" file %s, line %s"), + $this->getMessage() , $this->getFile() , $this->getLine()); + return $return; + } + + public function getErrno() + { + return $this->errno; + } } class BasicIPP { - // - // variables declaration - // - - // setup variables - - public $paths = array( - "root" => "/", - "admin" => "/admin/", - "printers" => "/printers/", - "jobs" => "/jobs/" - ); - public $http_timeout = 30; // timeout at http connection (seconds) 0 => default => 30. - public $http_data_timeout = 30; // data reading timeout (milliseconds) 0 => default => 30. - public $ssl = false; - public $debug_level = 3; // max 3: almost silent - public $alert_on_end_tag; // debugging purpose: echo "END tag OK" if (1 and reads while end tag) - public $with_exceptions = 0; // compatibility mode for old scripts - public $handle_http_exceptions = 1; - - // readables variables - - public $jobs = array(); - public $jobs_uri = array(); - public $status = array(); - public $response_completed = array(); - public $last_job = ""; - public $attributes; // object you can read: attributes after validateJob() - public $printer_attributes; // object you can read: printer's attributes after getPrinterAttributes() - public $job_attributes; // object you can read: last job attributes - public $jobs_attributes; // object you can read: jobs attributes after getJobs() - public $available_printers = array(); - public $printers_uri = array(); - public $debug = array(); - public $response; - - // protected variables; - protected $log_level = 2; // max 3: very verbose - protected $log_type = 3; // 3: file | 1: e-mail | 0: logger - protected $log_destination; // e-mail or file - protected $serveroutput; - protected $setup; - protected $stringjob; - protected $data; - protected $debug_count = 0; - protected $username; - protected $charset; - protected $password; - protected $requesring_user; - protected $client_hostname = "localhost"; - protected $stream; - protected $host = "localhost"; - protected $port = "631"; - protected $printer_uri; - protected $timeout = "20"; //20 secs - protected $errNo; - protected $errStr; - protected $datatype; - protected $datahead; - protected $datatail; - public $meta; - protected $operation_id; - protected $delay; - protected $error_generation; //devel feature - protected $debug_http = 0; - protected $no_disconnect; - protected $job_tags; - protected $operation_tags; - protected $index; - protected $collection; //RFC3382 - protected $collection_index; //RFC3382 - protected $collection_key = array(); //RFC3382 - protected $collection_depth = - 1; //RFC3382 - protected $end_collection = false; //RFC3382 - protected $collection_nbr = array(); //RFC3382 - protected $unix = false; // true -> use unix sockets instead of http - - // constructor - public function __construct() - { - $tz = getenv("date.timezone"); - if (!$tz) $tz = @date_default_timezone_get(); - date_default_timezone_set($tz); - $this->meta = new stdClass(); - $this->setup = new stdClass(); - $this->values = new stdClass(); - $this->serveroutput = new stdClass(); - $this->error_generation = new stdClass(); - $this->_parsing = new stdClass(); - self::_initTags(); - } - - /***************** - * - * PUBLIC FUNCTIONS - * - *******************/ - - // - // SETUP - // - - public function setPort($port = '631') - { - $this->port = $port; - self::_putDebug("Port is " . $this->port, 2); - } - - public function setUnix($socket = '/var/run/cups/cups.sock') - { - $this->host = $socket; - $this->unix = true; - self::_putDebug("Host is " . $this->host, 2); - } - - public function setHost($host = 'localhost') - { - $this->host = $host; - $this->unix = false; - self::_putDebug("Host is " . $this->host, 2); - } - - public function setTimeout($timeout) - { - $this->timeout = $timeout; - } - - public function setPrinterURI($uri) - { - $length = strlen($uri); - $length = chr($length); - while (strlen($length) < 2) $length = chr(0x00) . $length; - $this->meta->printer_uri = chr(0x45) // uri type | value-tag - . chr(0x00) . chr(0x0B) // name-length - . "printer-uri" // printer-uri | name - . $length . $uri; - $this->printer_uri = $uri; - self::_putDebug(sprintf(_("Printer URI: %s") , $uri) , 2); - $this->setup->uri = 1; - } - - public function setData($data) - { - $this->data = $data; - self::_putDebug("Data set", 2); - } - - public function setRawText() - { - $this->setup->datatype = 'TEXT'; - $this->meta->mime_media_type = ""; - $this->setup->mime_media_type = 1; - $this->datahead = chr(0x16); - if (is_readable($this->data)) - { - //It's a filename. Open and stream. - $data = fopen($this->data, "rb"); - while (!feof($data)) $output = fread($data, 8192); - } - else - { - $output = $this->data; - } - if (substr($output, -1, 1) != chr(0x0c)) if (!isset($this->setup->noFormFeed)) $this->datatail = chr(0x0c); - self::_putDebug(_("Forcing data to be interpreted as RAW TEXT") , 2); - } - - public function unsetRawText() - { - $this->setup->datatype = 'BINARY'; - $this->datahead = ''; - $this->datatail = ''; - self::_putDebug(_("Unset forcing data to be interpreted as RAW TEXT") , 2); - } - - public function setBinary() - { - self::unsetRawText(); - } - - public function setFormFeed() - { - $this->datatail = "\r\n" . chr(0x0c); - unset($this->setup->noFormFeed); - } - - public function unsetFormFeed() - { - $this->datatail = ''; - $this->setup->noFormFeed = 1; - } - - public function setCharset($charset = 'us-ascii') - { - $charset = strtolower($charset); - $this->charset = $charset; - $this->meta->charset = chr(0x47) // charset type | value-tag - . chr(0x00) . chr(0x12) // name-length - . "attributes-charset" // attributes-charset | name - . self::_giveMeStringLength($charset) // value-length - . $charset; // value - self::_putDebug(sprintf(_("Charset: %s") , $charset) , 2); - $this->setup->charset = 1; - } - - public function setLanguage($language = 'en_us') - { - $language = strtolower($language); - $this->meta->language = chr(0x48) // natural-language type | value-tag - . chr(0x00) . chr(0x1B) // name-length - . "attributes-natural-language" //attributes-natural-language - . self::_giveMeStringLength($language) // value-length - . $language; // value - self::_putDebug(sprintf(_("Language: %s") , $language) , 2); - $this->setup->language = 1; - } - - public function setDocumentFormat($mime_media_type = 'application/octet-stream') - { - self::setBinary(); - $length = chr(strlen($mime_media_type)); - while (strlen($length) < 2) $length = chr(0x00) . $length; - self::_putDebug(sprintf(_("mime type: %s") , $mime_media_type) , 2); - $this->meta->mime_media_type = chr(0x49) // document-format tag - . self::_giveMeStringLength('document-format') . 'document-format' // - . self::_giveMeStringLength($mime_media_type) . $mime_media_type; // value - $this->setup->mime_media_type = 1; - } - - // setDocumentFormat alias for backward compatibility - public function setMimeMediaType($mime_media_type = "application/octet-stream") - { - self::setDocumentFormat($mime_media_type); - } - - public function setCopies($nbrcopies = 1) - { - $this->meta->copies = ""; - if ($nbrcopies == 1 || !$nbrcopies) return true; - $copies = self::_integerBuild($nbrcopies); - $this->meta->copies = chr(0x21) // integer type | value-tag - . chr(0x00) . chr(0x06) // name-length - . "copies" // copies | name - . self::_giveMeStringLength($copies) // value-length - . $copies; - self::_putDebug(sprintf(_("Copies: %s") , $nbrcopies) , 2); - $this->setup->copies = 1; - } - - public function setDocumentName($document_name = "") - { - $this->meta->document_name = ""; - if (!$document_name) return true; - $document_name = substr($document_name, 0, 1023); - $length = strlen($document_name); - $length = chr($length); - while (strlen($length) < 2) $length = chr(0x00) . $length; - self::_putDebug(sprintf(_("document name: %s") , $document_name) , 2); - $this->meta->document_name = chr(0x41) // textWithoutLanguage tag - . chr(0x00) . chr(0x0d) // name-length - . "document-name" // mimeMediaType - . self::_giveMeStringLength($document_name) . $document_name; // value - - } - - public function setJobName($jobname = '', $absolute = false) - { - $this->meta->jobname = ''; - if ($jobname == '') - { - $this->meta->jobname = ''; - return true; - } - $postpend = date('-H:i:s-') . $this->_setJobId(); - if ($absolute) $postpend = ''; - if (isset($this->values->jobname) && $jobname == '(PHP)') - { - $jobname = $this->values->jobname; - } - $this->values->jobname = $jobname; - $jobname.= $postpend; - $this->meta->jobname = chr(0x42) // nameWithoutLanguage type || value-tag - . chr(0x00) . chr(0x08) // name-length - . "job-name" // job-name || name - . self::_giveMeStringLength($jobname) // value-length - . $jobname; // value - self::_putDebug(sprintf(_("Job name: %s") , $jobname) , 2); - $this->setup->jobname = 1; - } - - public function setUserName($username = 'PHP-SERVER') - { - $this->requesting_user = $username; - $this->meta->username = ''; - if (!$username) return true; - if ($username == 'PHP-SERVER' && isset($this->meta->username)) return TRUE; - /* - $value_length = 0x00; - for ($i = 0; $i < strlen($username); $i++) - { - $value_length+= 0x01; - } - $value_length = chr($value_length); - while (strlen($value_length) < 2) $value_length = chr(0x00) . $value_length; - */ - $this->meta->username = chr(0x42) // keyword type || value-tag - . chr(0x00) . chr(0x14) // name-length - . "requesting-user-name" - . self::_giveMeStringLength($username) // value-length - . $username; - self::_putDebug(sprintf(_("Username: %s") , $username) , 2); - $this->setup->username = 1; - } - - public function setAuthentification($username, $password) - { - self::setAuthentication($username, $password); - } - - public function setAuthentication($username, $password) - { - $this->password = $password; - $this->username = $username; - self::_putDebug(_("Setting password") , 2); - $this->setup->password = 1; - } - - public function setSides($sides = 2) - { - $this->meta->sides = ''; - if (!$sides) return true; - switch ($sides) - { - case 1: - $sides = "one-sided"; - break; - - case 2: - $sides = "two-sided-long-edge"; - break; - - case "2CE": - $sides = "two-sided-short-edge"; - break; - - default: - $sides = $sides; // yeah, what ? - break; - } - $this->meta->sides = chr(0x44) // keyword type | value-tag - . chr(0x00) . chr(0x05) // name-length - . "sides" // sides | name - . self::_giveMeStringLength($sides) // value-length - . $sides; // one-sided | value - self::_putDebug(sprintf(_("Sides value set to %s") , $sides) , 2); - } - - public function setFidelity() - { - // whether the server can't replace any attributes - // (eg, 2 sided print is not possible, - // so print one sided) and DO NOT THE JOB. - $this->meta->fidelity = chr(0x22) // boolean type | value-tag - . chr(0x00) . chr(0x16) // name-length - . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name - . chr(0x00) . chr(0x01) // value-length - . chr(0x01); // true | value - self::_putDebug(_("Fidelity attribute is set (paranoid mode)") , 3); - } - - public function unsetFidelity() - { - // whether the server can replace any attributes - // (eg, 2 sided print is not possible, - // so print one sided) and DO THE JOB. - $this->meta->fidelity = chr(0x22) // boolean type | value-tag - . chr(0x00) . chr(0x16) // name-length - . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name - . chr(0x00) . chr(0x01) // value-length - . chr(0x00); // false | value - self::_putDebug(_("Fidelity attribute is unset") , 2); - } - - public function setMessage($message = '') - { - $this->meta->message = ''; - if (!$message) return true; - $this->meta->message = - chr(0x41) // attribute type = textWithoutLanguage - . chr(0x00) - . chr(0x07) - . "message" - . self::_giveMeStringLength(substr($message, 0, 127)) - . substr($message, 0, 127); - self::_putDebug(sprintf(_('Setting message to "%s"') , $message) , 2); - } - - public function setPageRanges($page_ranges) - { - // $pages_ranges = string: "1:5 10:25 40:52 ..." - // to unset, specify an empty string. - $this->meta->page_range = ''; - if (!$page_ranges) return true; - $page_ranges = trim(str_replace("-", ":", $page_ranges)); - $first = true; - #$page_ranges = split(' ', $page_ranges); - $page_ranges = preg_split('# #', $page_ranges); - foreach($page_ranges as $page_range) - { - $value = self::_rangeOfIntegerBuild($page_range); - if ($first) - { - $this->meta->page_ranges .= - $this->tags_types['rangeOfInteger']['tag'] - . self::_giveMeStringLength('page-ranges') - . 'page-ranges' - . self::_giveMeStringLength($value) - . $value; - } - else - { - $this->meta->page_ranges .= - $this->tags_types['rangeOfInteger']['tag'] - . self::_giveMeStringLength('') - . self::_giveMeStringLength($value) - . $value; - $first = false; - } - } - } - - public function setAttribute($attribute, $values) - { - $operation_attributes_tags = array_keys($this->operation_tags); - $job_attributes_tags = array_keys($this->job_tags); - $printer_attributes_tags = array_keys($this->printer_tags); - self::unsetAttribute($attribute); - if (in_array($attribute, $operation_attributes_tags)) - { - if (!is_array($values)) - { - self::_setOperationAttribute($attribute, $values); - } - else - { - foreach($values as $value) - { - self::_setOperationAttribute($attribute, $value); - } - } - } - elseif (in_array($attribute, $job_attributes_tags)) - { - if (!is_array($values)) - { - self::_setJobAttribute($attribute, $values); - } - else - { - foreach($values as $value) - { - self::_setJobAttribute($attribute, $value); - } - } - } - elseif (in_array($attribute, $printer_attributes_tags)) - { - if (!is_array($values)) - { - self::_setPrinterAttribute($attribute, $values); - } - else - { - foreach($values as $value) - { - self::_setPrinterAttribute($attribute, $value); - } - } - } - else - { - trigger_error( - sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , E_USER_NOTICE); - self::_putDebug( - sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , 3); - self::_errorLog( - sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , 2); - return FALSE; - } - } - - public function unsetAttribute($attribute) - { - $operation_attributes_tags = array_keys($this->operation_tags); - $job_attributes_tags = array_keys($this->job_tags); - $printer_attributes_tags = array_keys($this->printer_tags); - if (in_array($attribute, $operation_attributes_tags)) - { - unset( - $this->operation_tags[$attribute]['value'], - $this->operation_tags[$attribute]['systag'] - ); - } - elseif (in_array($attribute, $job_attributes_tags)) - { - unset( - $this->job_tags[$attribute]['value'], - $this->job_tags[$attribute]['systag'] - ); - } - elseif (in_array($attribute, $printer_attributes_tags)) - { - unset( - $this->printer_tags[$attribute]['value'], - $this->printer_tags[$attribute]['systag'] - ); - } - else - { - trigger_error( - sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , E_USER_NOTICE); - self::_putDebug( - sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , 3); - self::_errorLog( - sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , 2); - return FALSE; - } - return true; - } - - // - // LOGGING / DEBUGGING - // - - public function setLog($log_destination, $destination_type = 'file', $level = 2) - { - - if (is_string($log_destination) && !empty($log_destination)) - { - $this->log_destination = $log_destination; - } - - switch ($destination_type) - { - case 'file': - case 3: - $this->log_destination = $log_destination; - $this->log_type = 3; - break; - - case 'logger': - case 0: - $this->log_destination = ''; - $this->log_type = 0; - break; - - case 'e-mail': - case 1: - $this->log_destination = $log_destination; - $this->log_type = 1; - break; - } - $this->log_level = $level; - } - - public function printDebug() - { - for ($i = 0; $i < $this->debug_count; $i++) - { - echo $this->debug[$i], "\n"; - } - $this->debug = array(); - $this->debug_count = 0; - } - - public function getDebug() - { - $debug = ''; - for ($i = 0; $i < $this->debug_count; $i++) - { - $debug.= $this->debug[$i]; - } - $this->debug = array(); - $this->debug_count = 0; - return $debug; - } - - // - // OPERATIONS - // - - public function printJob() - { - // this BASIC version of printJob do not parse server - // output for job's attributes - self::_putDebug( - sprintf( - "************** Date: %s ***********", - date('Y-m-d H:i:s') - ) - ); - if (!$this->_stringJob()) return FALSE; - if (is_readable($this->data)) - { - self::_putDebug(_("Printing a FILE")); - $this->output = $this->stringjob; - if ($this->setup->datatype == "TEXT") - { - $this->output.= chr(0x16); - } - $post_values = array( - "Content-Type" => "application/ipp", - "Data" => $this->output, - "File" => $this->data - ); - if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed)) - { - $post_values = array_merge( - $post_values, - array( - "Filetype" => "TEXT" - ) - ); - } - } - else - { - self::_putDebug(_("Printing DATA")); - $this->output = - $this->stringjob - . $this->datahead - . $this->data - . $this->datatail; - $post_values = array( - "Content-Type" => "application/ipp", - "Data" => $this->output - ); - } - if (self::_sendHttp($post_values, $this->paths["printers"])) - { - self::_parseServerOutput(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) - { - $this->status = array_merge($this->status, array( - $this->serveroutput->status - )); - if ($this->serveroutput->status == "successfull-ok") - { - self::_errorLog( - sprintf("printing job %s: ", $this->last_job) - . $this->serveroutput->status, - 3); - } - else - { - self::_errorLog( - sprintf("printing job: ", $this->last_job) - . $this->serveroutput->status, - 1); - } - return $this->serveroutput->status; - } - - $this->status = - array_merge($this->status, array("OPERATION FAILED")); - $this->jobs = - array_merge($this->jobs, array("")); - $this->jobs_uri = - array_merge($this->jobs_uri, array("")); - - self::_errorLog("printing job : OPERATION FAILED", 1); - return false; - } - - - /****************** - * - * PROTECTED FUNCTIONS - * - *******************/ - - // - // HTTP OUTPUT - // - - protected function _sendHttp($post_values, $uri) - { - /* - This function Copyright (C) 2005-2006 Thomas Harding, Manuel Lemos - */ - $this->response_completed[] = "no"; - unset($this->serverouptut); - self::_putDebug(_("Processing HTTP request") , 2); - $this->serveroutput->headers = array(); - $this->serveroutput->body = ""; - $http = new http_class; - if (!$this->unix) $http->host = $this->host; - else $http->host = "localhost"; - $http->with_exceptions = $this->with_exceptions; - if ($this->debug_http) - { - $http->debug = 1; - $http->html_debug = 0; - } - else - { - $http->debug = 0; - $http->html_debug = 0; - } - $url = "http://" . $this->host; - if ($this->ssl) $url = "https://" . $this->host; - if ($this->unix) $url = "unix://" . $this->host; - $http->port = $this->port; - $http->timeout = $this->http_timeout; - $http->data_timeout = $this->http_data_timeout; - $http->force_multipart_form_post = false; - $http->user = $this->username; - $http->password = $this->password; - $error = $http->GetRequestArguments($url, $arguments); - $arguments["RequestMethod"] = "POST"; - $arguments["Headers"] = array( - "Content-Type" => "application/ipp" + public $paths = array( + "root" => "/", + "admin" => "/admin/", + "printers" => "/printers/", + "jobs" => "/jobs/" ); - $arguments["BodyStream"] = array( - array( - "Data" => $post_values["Data"] - ) - ); - if (isset($post_values["File"])) $arguments["BodyStream"][] = array( - "File" => $post_values["File"] - ); - if (isset($post_values["FileType"]) - && !strcmp($post_values["FileType"], "TEXT")) - { - $arguments["BodyStream"][] = array("Data" => Chr(12)); - } - $arguments["RequestURI"] = $uri; - if ($this->with_exceptions && $this->handle_http_exceptions) - { - try - { - $success = $http->Open($arguments); - } - catch(httpException $e) - { - throw new ippException( - sprintf("http error: %s", $e->getMessage()), - $e->getErrno()); - } - } - else - { - $success = $http->Open($arguments); - } - if ($success[0] == true) - { - $success = $http->SendRequest($arguments); - if ($success[0] == true) - { - self::_putDebug("H T T P R E Q U E S T :"); - self::_putDebug("Request headers:"); - for (Reset($http->request_headers) , $header = 0; $header < count($http->request_headers); Next($http->request_headers) , $header++) + public $http_timeout = 30; // timeout at http connection (seconds) 0 => default => 30. + public $http_data_timeout = 30; // data reading timeout (milliseconds) 0 => default => 30. + public $ssl = false; + public $debug_level = 3; // max 3: almost silent + public $alert_on_end_tag; // debugging purpose: echo "END tag OK" if (1 and reads while end tag) + public $with_exceptions = 0; // compatibility mode for old scripts + public $handle_http_exceptions = 1; + + // readables variables + public $jobs = array(); + public $jobs_uri = array(); + public $status = array(); + public $response_completed = array(); + public $last_job = ""; + public $attributes; // object you can read: attributes after validateJob() + public $printer_attributes; // object you can read: printer's attributes after getPrinterAttributes() + public $job_attributes; // object you can read: last job attributes + public $jobs_attributes; // object you can read: jobs attributes after getJobs() + public $available_printers = array(); + public $printer_map = array(); + public $printers_uri = array(); + public $debug = array(); + public $response; + public $meta; + + // protected variables; + protected $log_level = 2; // max 3: very verbose + protected $log_type = 3; // 3: file | 1: e-mail | 0: logger + protected $log_destination; // e-mail or file + protected $serveroutput; + protected $setup; + protected $stringjob; + protected $data; + protected $debug_count = 0; + protected $username; + protected $charset; + protected $password; + protected $requesring_user; + protected $client_hostname = "localhost"; + protected $stream; + protected $host = "localhost"; + protected $port = "631"; + protected $requesting_user = ''; + protected $printer_uri; + protected $timeout = "20"; //20 secs + protected $errNo; + protected $errStr; + protected $datatype; + protected $datahead; + protected $datatail; + protected $operation_id; + protected $delay; + protected $error_generation; //devel feature + protected $debug_http = 0; + protected $no_disconnect; + protected $job_tags; + protected $operation_tags; + protected $index; + protected $collection; //RFC3382 + protected $collection_index; //RFC3382 + protected $collection_key = array(); //RFC3382 + protected $collection_depth = - 1; //RFC3382 + protected $end_collection = false; //RFC3382 + protected $collection_nbr = array(); //RFC3382 + protected $unix = false; // true -> use unix sockets instead of http + protected $output; + + public function __construct() { - $header_name = Key($http->request_headers); - if (GetType($http->request_headers[$header_name]) == "array") - { - for ($header_value = 0; $header_value < count($http->request_headers[$header_name]); $header_value++) - { - self::_putDebug($header_name . ": " . $http->request_headers[$header_name][$header_value]); - } - } - else - { - self::_putDebug($header_name . ": " . $http->request_headers[$header_name]); - } + $tz = getenv("date.timezone"); + if (!$tz) + { + $tz = @date_default_timezone_get(); + } + + date_default_timezone_set($tz); + $this->meta = new \stdClass(); + $this->setup = new \stdClass(); + $this->values = new \stdClass(); + $this->serveroutput = new \stdClass(); + $this->error_generation = new \stdClass(); + $this->_parsing = new \stdClass(); + self::_initTags(); } - self::_putDebug("Request body:"); - self::_putDebug( - htmlspecialchars($http->request_body) - . "*********** END REQUEST BODY *********" + + public function setPort($port = '631') + { + $this->port = $port; + self::_putDebug("Port is " . $this->port, 2); + } + + public function setUnix($socket = '/var/run/cups/cups.sock') + { + $this->host = $socket; + $this->unix = true; + self::_putDebug("Host is " . $this->host, 2); + } + + public function setHost($host = 'localhost') + { + $this->host = $host; + $this->unix = false; + self::_putDebug("Host is " . $this->host, 2); + } + + public function setTimeout($timeout) + { + $this->timeout = $timeout; + } + + public function setPrinterURI($uri) + { + $length = strlen($uri); + $length = chr($length); + while (strlen($length) < 2) $length = chr(0x00) . $length; + $this->meta->printer_uri = chr(0x45) // uri type | value-tag + . chr(0x00) . chr(0x0B) // name-length + . "printer-uri" // printer-uri | name + . $length . $uri; + $this->printer_uri = $uri; + self::_putDebug(sprintf(_("Printer URI: %s") , $uri) , 2); + $this->setup->uri = 1; + } + + public function setData($data) + { + $this->data = $data; + self::_putDebug("Data set", 2); + } + + public function setRawText() + { + $this->setup->datatype = 'TEXT'; + $this->meta->mime_media_type = ""; + $this->setup->mime_media_type = 1; + $this->datahead = chr(0x16); + if (is_readable($this->data)) + { + //It's a filename. Open and stream. + $data = fopen($this->data, "rb"); + while (!feof($data)) $output = fread($data, 8192); + } + else + { + $output = $this->data; + } + if (substr($output, -1, 1) != chr(0x0c)) { + if (!isset($this->setup->noFormFeed)) + { + $this->datatail = chr(0x0c); + } + } + self::_putDebug(_("Forcing data to be interpreted as RAW TEXT") , 2); + } + + public function unsetRawText() + { + $this->setup->datatype = 'BINARY'; + $this->datahead = ''; + $this->datatail = ''; + self::_putDebug(_("Unset forcing data to be interpreted as RAW TEXT") , 2); + } + + public function setBinary() + { + self::unsetRawText(); + } + + public function setFormFeed() + { + $this->datatail = "\r\n" . chr(0x0c); + unset($this->setup->noFormFeed); + } + + public function unsetFormFeed() + { + $this->datatail = ''; + $this->setup->noFormFeed = 1; + } + + public function setCharset($charset = 'utf-8') + { + $charset = strtolower($charset); + $this->charset = $charset; + $this->meta->charset = chr(0x47) // charset type | value-tag + . chr(0x00) . chr(0x12) // name-length + . "attributes-charset" // attributes-charset | name + . self::_giveMeStringLength($charset) // value-length + . $charset; // value + self::_putDebug(sprintf(_("Charset: %s") , $charset) , 2); + $this->setup->charset = 1; + } + + public function setLanguage($language = 'en_us') + { + $language = strtolower($language); + $this->meta->language = chr(0x48) // natural-language type | value-tag + . chr(0x00) . chr(0x1B) // name-length + . "attributes-natural-language" //attributes-natural-language + . self::_giveMeStringLength($language) // value-length + . $language; // value + self::_putDebug(sprintf(_("Language: %s") , $language) , 2); + $this->setup->language = 1; + } + + public function setDocumentFormat($mime_media_type = 'application/octet-stream') + { + self::setBinary(); + $length = chr(strlen($mime_media_type)); + while (strlen($length) < 2) $length = chr(0x00) . $length; + self::_putDebug(sprintf(_("mime type: %s") , $mime_media_type) , 2); + $this->meta->mime_media_type = chr(0x49) // document-format tag + . self::_giveMeStringLength('document-format') . 'document-format' // + . self::_giveMeStringLength($mime_media_type) . $mime_media_type; // value + $this->setup->mime_media_type = 1; + } + + // setDocumentFormat alias for backward compatibility + public function setMimeMediaType($mime_media_type = "application/octet-stream") + { + self::setDocumentFormat($mime_media_type); + } + + public function setCopies($nbrcopies = 1) + { + $this->meta->copies = ""; + + if ($nbrcopies == 1 || !$nbrcopies) + { + return true; + } + + $copies = self::_integerBuild($nbrcopies); + $this->meta->copies = chr(0x21) // integer type | value-tag + . chr(0x00) . chr(0x06) // name-length + . "copies" // copies | name + . self::_giveMeStringLength($copies) // value-length + . $copies; + self::_putDebug(sprintf(_("Copies: %s") , $nbrcopies) , 2); + $this->setup->copies = 1; + } + + public function setDocumentName($document_name = "") + { + $this->meta->document_name = ""; + if (!$document_name) { + return true; + } + $document_name = substr($document_name, 0, 1023); + $length = strlen($document_name); + $length = chr($length); + while (strlen($length) < 2) $length = chr(0x00) . $length; + self::_putDebug(sprintf(_("document name: %s") , $document_name) , 2); + $this->meta->document_name = chr(0x41) // textWithoutLanguage tag + . chr(0x00) . chr(0x0d) // name-length + . "document-name" // mimeMediaType + . self::_giveMeStringLength($document_name) . $document_name; // value + + } + + public function setJobName($jobname = '', $absolute = false) + { + $this->meta->jobname = ''; + if ($jobname == '') + { + $this->meta->jobname = ''; + return true; + } + $postpend = date('-H:i:s-') . $this->_setJobId(); + if ($absolute) { + $postpend = ''; + } + if (isset($this->values->jobname) && $jobname == '(PHP)') + { + $jobname = $this->values->jobname; + } + $this->values->jobname = $jobname; + $jobname.= $postpend; + $this->meta->jobname = chr(0x42) // nameWithoutLanguage type || value-tag + . chr(0x00) . chr(0x08) // name-length + . "job-name" // job-name || name + . self::_giveMeStringLength($jobname) // value-length + . $jobname; // value + self::_putDebug(sprintf(_("Job name: %s") , $jobname) , 2); + $this->setup->jobname = 1; + } + + public function setUserName($username = 'PHP-SERVER') + { + $this->requesting_user = $username; + $this->meta->username = ''; + if (!$username) { + return true; + } + if ($username == 'PHP-SERVER' && isset($this->meta->username)) { + return TRUE; + } + /* + $value_length = 0x00; + for ($i = 0; $i < strlen($username); $i++) + { + $value_length+= 0x01; + } + $value_length = chr($value_length); + while (strlen($value_length) < 2) $value_length = chr(0x00) . $value_length; + */ + $this->meta->username = chr(0x42) // keyword type || value-tag + . chr(0x00) . chr(0x14) // name-length + . "requesting-user-name" + . self::_giveMeStringLength($username) // value-length + . $username; + self::_putDebug(sprintf(_("Username: %s") , $username) , 2); + $this->setup->username = 1; + } + + public function setAuthentification($username, $password) + { + self::setAuthentication($username, $password); + } + + public function setAuthentication($username, $password) + { + $this->password = $password; + $this->username = $username; + self::_putDebug(_("Setting password") , 2); + $this->setup->password = 1; + } + + public function setSides($sides = 2) + { + $this->meta->sides = ''; + if (!$sides) + { + return true; + } + + switch ($sides) + { + case 1: + $sides = "one-sided"; + break; + + case 2: + $sides = "two-sided-long-edge"; + break; + + case "2CE": + $sides = "two-sided-short-edge"; + break; + } + + $this->meta->sides = chr(0x44) // keyword type | value-tag + . chr(0x00) . chr(0x05) // name-length + . "sides" // sides | name + . self::_giveMeStringLength($sides) // value-length + . $sides; // one-sided | value + self::_putDebug(sprintf(_("Sides value set to %s") , $sides) , 2); + } + + public function setFidelity() + { + // whether the server can't replace any attributes + // (eg, 2 sided print is not possible, + // so print one sided) and DO NOT THE JOB. + $this->meta->fidelity = chr(0x22) // boolean type | value-tag + . chr(0x00) . chr(0x16) // name-length + . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name + . chr(0x00) . chr(0x01) // value-length + . chr(0x01); // true | value + self::_putDebug(_("Fidelity attribute is set (paranoid mode)") , 3); + } + + public function unsetFidelity() + { + // whether the server can replace any attributes + // (eg, 2 sided print is not possible, + // so print one sided) and DO THE JOB. + $this->meta->fidelity = chr(0x22) // boolean type | value-tag + . chr(0x00) . chr(0x16) // name-length + . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name + . chr(0x00) . chr(0x01) // value-length + . chr(0x00); // false | value + self::_putDebug(_("Fidelity attribute is unset") , 2); + } + + public function setMessage($message = '') + { + $this->meta->message = ''; + if (!$message) { + return true; + } + $this->meta->message = + chr(0x41) // attribute type = textWithoutLanguage + . chr(0x00) + . chr(0x07) + . "message" + . self::_giveMeStringLength(substr($message, 0, 127)) + . substr($message, 0, 127); + self::_putDebug(sprintf(_('Setting message to "%s"') , $message) , 2); + } + + public function setPageRanges($page_ranges) + { + // $pages_ranges = string: "1:5 10:25 40:52 ..." + // to unset, specify an empty string. + $this->meta->page_range = ''; + if (!$page_ranges) { + return true; + } + $page_ranges = trim(str_replace("-", ":", $page_ranges)); + $first = true; + #$page_ranges = split(' ', $page_ranges); + $page_ranges = preg_split('# #', $page_ranges); + foreach($page_ranges as $page_range) + { + $value = self::_rangeOfIntegerBuild($page_range); + if ($first) + { + $this->meta->page_ranges .= + $this->tags_types['rangeOfInteger']['tag'] + . self::_giveMeStringLength('page-ranges') + . 'page-ranges' + . self::_giveMeStringLength($value) + . $value; + } + else + { + $this->meta->page_ranges .= + $this->tags_types['rangeOfInteger']['tag'] + . self::_giveMeStringLength('') + . self::_giveMeStringLength($value) + . $value; + $first = false; + } + } + } + + public function setAttribute($attribute, $values) + { + $operation_attributes_tags = array_keys($this->operation_tags); + $job_attributes_tags = array_keys($this->job_tags); + $printer_attributes_tags = array_keys($this->printer_tags); + self::unsetAttribute($attribute); + if (in_array($attribute, $operation_attributes_tags)) + { + if (!is_array($values)) + { + self::_setOperationAttribute($attribute, $values); + } + else + { + foreach($values as $value) + { + self::_setOperationAttribute($attribute, $value); + } + } + } + elseif (in_array($attribute, $job_attributes_tags)) + { + if (!is_array($values)) + { + self::_setJobAttribute($attribute, $values); + } + else + { + foreach($values as $value) + { + self::_setJobAttribute($attribute, $value); + } + } + } + elseif (in_array($attribute, $printer_attributes_tags)) + { + if (!is_array($values)) + { + self::_setPrinterAttribute($attribute, $values); + } + else + { + foreach($values as $value) + { + self::_setPrinterAttribute($attribute, $value); + } + } + } + else + { + trigger_error( + sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , E_USER_NOTICE); + self::_putDebug( + sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , 3); + self::_errorLog( + sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , 2); + return FALSE; + } + } + + public function unsetAttribute($attribute) + { + $operation_attributes_tags = array_keys($this->operation_tags); + $job_attributes_tags = array_keys($this->job_tags); + $printer_attributes_tags = array_keys($this->printer_tags); + if (in_array($attribute, $operation_attributes_tags)) + { + unset( + $this->operation_tags[$attribute]['value'], + $this->operation_tags[$attribute]['systag'] ); - $i = 0; - $headers = array(); - unset($this->serveroutput->headers); - $http->ReadReplyHeaders($headers); - self::_putDebug("H T T P R E S P O N S E :"); - self::_putDebug("Response headers:"); - for (Reset($headers) , $header = 0; $header < count($headers); Next($headers) , $header++) - { - $header_name = Key($headers); - if (GetType($headers[$header_name]) == "array") - { - for ($header_value = 0; $header_value < count($headers[$header_name]); $header_value++) - { - self::_putDebug($header_name . ": " . $headers[$header_name][$header_value]); - $this->serveroutput->headers[$i] = - $header_name . ": " - . $headers[$header_name][$header_value]; - $i++; - } - } - else - { - self::_putDebug($header_name . ": " . $headers[$header_name]); - $this->serveroutput->headers[$i] = - $header_name - . ": " - . $headers[$header_name]; - $i++; - } + } + elseif (in_array($attribute, $job_attributes_tags)) + { + unset( + $this->job_tags[$attribute]['value'], + $this->job_tags[$attribute]['systag'] + ); + } + elseif (in_array($attribute, $printer_attributes_tags)) + { + unset( + $this->printer_tags[$attribute]['value'], + $this->printer_tags[$attribute]['systag'] + ); + } + else + { + trigger_error( + sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , E_USER_NOTICE); + self::_putDebug( + sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , 3); + self::_errorLog( + sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , 2); + return FALSE; + } + return true; } - self::_putDebug("\n\nResponse body:\n"); - $this->serveroutput->body = ""; - for (;;) - { - $http->ReadReplyBody($body, 1024); - if (strlen($body) == 0) break; - self::_putDebug(htmlentities($body)); - $this->serveroutput->body.= $body; - } - self::_putDebug("********* END RESPONSE BODY ********"); - } - } - $http->Close(); - return true; - } - - // - // INIT - // - - protected function _initTags() - { - $this->tags_types = array( - "unsupported" => array( - "tag" => chr(0x10) , - "build" => "" - ) , - "reserved" => array( - "tag" => chr(0x11) , - "build" => "" - ) , - "unknown" => array( - "tag" => chr(0x12) , - "build" => "" - ) , - "no-value" => array( - "tag" => chr(0x13) , - "build" => "no_value" - ) , - "integer" => array( - "tag" => chr(0x21) , - "build" => "integer" - ) , - "boolean" => array( - "tag" => chr(0x22) , - "build" => "boolean" - ) , - "enum" => array( - "tag" => chr(0x23) , - "build" => "enum" - ) , - "octetString" => array( - "tag" => chr(0x30) , - "build" => "octet_string" - ) , - "datetime" => array( - "tag" => chr(0x31) , - "build" => "datetime" - ) , - "resolution" => array( - "tag" => chr(0x32) , - "build" => "resolution" - ) , - "rangeOfInteger" => array( - "tag" => chr(0x33) , - "build" => "range_of_integers" - ) , - "textWithLanguage" => array( - "tag" => chr(0x35) , - "build" => "string" - ) , - "nameWithLanguage" => array( - "tag" => chr(0x36) , - "build" => "string" - ) , - /* - "text" => array ("tag" => chr(0x40), - "build" => "string"), - "text string" => array ("tag" => chr(0x40), - "build" => "string"), + // + // LOGGING / DEBUGGING + // + /** + * Sets log file destination. Creates the file if has permission. + * + * @param string $log_destination + * @param string $destination_type + * @param int $level + * + * @throws ippException */ - "textWithoutLanguage" => array( - "tag" => chr(0x41) , - "build" => "string" - ) , - "nameWithoutLanguage" => array( - "tag" => chr(0x42) , - "buid" => "string" - ) , - "keyword" => array( - "tag" => chr(0x44) , - "build" => "string" - ) , - "uri" => array( - "tag" => chr(0x45) , - "build" => "string" - ) , - "uriScheme" => array( - "tag" => chr(0x46) , - "build" => "string" - ) , - "charset" => array( - "tag" => chr(0x47) , - "build" => "string" - ) , - "naturalLanguage" => array( - "tag" => chr(0x48) , - "build" => "string" - ) , - "mimeMediaType" => array( - "tag" => chr(0x49) , - "build" => "string" - ) , - "extendedAttributes" => array( - "tag" => chr(0x7F) , - "build" => "extended" - ) , - ); - $this->operation_tags = array( - "compression" => array( - "tag" => "keyword" - ) , - "document-natural-language" => array( - "tag" => "naturalLanguage" - ) , - "job-k-octets" => array( - "tag" => "integer" - ) , - "job-impressions" => array( - "tag" => "integer" - ) , - "job-media-sheets" => array( - "tag" => "integer" - ) , - ); - $this->job_tags = array( - "job-priority" => array( - "tag" => "integer" - ) , - "job-hold-until" => array( - "tag" => "keyword" - ) , - "job-sheets" => array( - "tag" => "keyword" - ) , //banner page - "multiple-document-handling" => array( - "tag" => "keyword" - ) , - //"copies" => array("tag" => "integer"), - "finishings" => array( - "tag" => "enum" - ) , - //"page-ranges" => array("tag" => "rangeOfInteger"), // has its own function - //"sides" => array("tag" => "keyword"), // has its own function - "number-up" => array( - "tag" => "integer" - ) , - "orientation-requested" => array( - "tag" => "enum" - ) , - "media" => array( - "tag" => "keyword" - ) , - "printer-resolution" => array( - "tag" => "resolution" - ) , - "print-quality" => array( - "tag" => "enum" - ) , - "job-message-from-operator" => array( - "tag" => "textWithoutLanguage" - ) , - ); - $this->printer_tags = array( - "requested-attributes" => array( - "tag" => "keyword" - ) - ); - } - - // - // SETUP - // - - protected function _setOperationId() - { - $prepend = ''; - $this->operation_id+= 1; - $this->meta->operation_id = self::_integerBuild($this->operation_id); - self::_putDebug("operation id is: " . $this->operation_id, 2); - } - - protected function _setJobId() - { - $this->meta->jobid+= 1; - $prepend = ''; - $prepend_length = 4 - strlen($this->meta->jobid); - for ($i = 0; $i < $prepend_length; $i++) $prepend.= '0'; - return $prepend . $this->meta->jobid; - } - - protected function _setJobUri($job_uri) - { - $this->meta->job_uri = chr(0x45) // type uri - . chr(0x00) . chr(0x07) // name-length - . "job-uri" - //. chr(0x00).chr(strlen($job_uri)) - . self::_giveMeStringLength($job_uri) . $job_uri; - self::_putDebug("job-uri is: " . $job_uri, 2); - } - - // - // RESPONSE PARSING - // - - protected function _parseServerOutput() - { - $this->serveroutput->response = array(); - if (!self::_parseHttpHeaders()) return FALSE; - $this->_parsing->offset = 0; - self::_parseIppVersion(); - self::_parseStatusCode(); - self::_parseRequestID(); - $this->_parseResponse(); - //devel - self::_putDebug( - sprintf("***** IPP STATUS: %s ******", $this->serveroutput->status), - 4); - self::_putDebug("****** END OF OPERATION ****"); - return true; - } - - protected function _parseHttpHeaders() - { - $response = ""; - switch ($this->serveroutput->headers[0]) - { - case "http/1.1 200 ok: ": - $this->serveroutput->httpstatus = "HTTP/1.1 200 OK"; - $response = "OK"; - break; - - // primitive http/1.0 for Lexmark printers (from Rick Baril) - case "http/1.0 200 ok: ": - $this->serveroutput->httpstatus = "HTTP/1.0 200 OK"; - $response = "OK"; - break; - - case "http/1.1 100 continue: ": - $this->serveroutput->httpstatus = "HTTP/1.1 100 CONTINUE"; - $response = "OK"; - break; - - case "": - $this->serveroutput->httpstatus = "HTTP/1.1 000 No Response From Server"; - $this->serveroutput->status = "HTTP-ERROR-000_NO_RESPONSE_FROM_SERVER"; - trigger_error("No Response From Server", E_USER_WARNING); - self::_errorLog("No Response From Server", 1); - $this->disconnected = 1; - return FALSE; - break; - - default: - $server_response = preg_replace("/: $/", '', $this->serveroutput->headers[0]); - #$strings = split(' ', $server_response, 3); - $strings = preg_split('# #', $server_response, 3); - $errno = $strings[1]; - $string = strtoupper(str_replace(' ', '_', $strings[2])); - trigger_error( - sprintf(_("server responds %s") , $server_response), - E_USER_WARNING); - self::_errorLog("server responds " . $server_response, 1); - $this->serveroutput->httpstatus = - strtoupper($strings[0]) - . " " - . $errno - . " " - . ucfirst($strings[2]); - - $this->serveroutput->status = - "HTTP-ERROR-" - . $errno - . "-" - . $string; - $this->disconnected = 1; - return FALSE; - break; - } - unset($this->serveroutput->headers); - return TRUE; - } - - protected function _parseIppVersion() - { - $ippversion = - (ord($this->serveroutput->body[$this->_parsing->offset]) * 256) - + ord($this->serveroutput->body[$this->_parsing->offset + 1]); - switch ($ippversion) - { - case 0x0101: - $this->serveroutput->ipp_version = "1.1"; - break; - - default: - $this->serveroutput->ipp_version = - sprintf("%u.%u (Unknown)", - ord($this->serveroutput->body[$this->_parsing->offset]) * 256, - ord($this->serveroutput->body[$this->_parsing->offset + 1])); - break; - } - self::_putDebug("I P P R E S P O N S E :\n\n"); - self::_putDebug( - sprintf("IPP version %s%s: %s", - ord($this->serveroutput->body[$this->_parsing->offset]), - ord($this->serveroutput->body[$this->_parsing->offset + 1]), - $this->serveroutput->ipp_version)); - $this->_parsing->offset+= 2; - return; - } - - protected function _parseStatusCode() - { - $status_code = - (ord($this->serveroutput->body[$this->_parsing->offset]) * 256) - + ord($this->serveroutput->body[$this->_parsing->offset + 1]); - $this->serveroutput->status = "NOT PARSED"; - $this->_parsing->offset+= 2; - if (strlen($this->serveroutput->body) < $this->_parsing->offset) - { - return false; - } - if ($status_code < 0x00FF) - { - $this->serveroutput->status = "successfull"; - } - elseif ($status_code < 0x01FF) - { - $this->serveroutput->status = "informational"; - } - elseif ($status_code < 0x02FF) - { - $this->serveroutput->status = "redirection"; - } - elseif ($status_code < 0x04FF) - { - $this->serveroutput->status = "client-error"; - } - elseif ($status_code < 0x05FF) - { - $this->serveroutput->status = "server-error"; - } - switch ($status_code) - { - case 0x0000: - $this->serveroutput->status = "successfull-ok"; - break; - - case 0x0001: - $this->serveroutput->status = "successful-ok-ignored-or-substituted-attributes"; - break; - - case 0x002: - $this->serveroutput->status = "successful-ok-conflicting-attributes"; - break; - - case 0x0400: - $this->serveroutput->status = "client-error-bad-request"; - break; - - case 0x0401: - $this->serveroutput->status = "client-error-forbidden"; - break; - - case 0x0402: - $this->serveroutput->status = "client-error-not-authenticated"; - break; - - case 0x0403: - $this->serveroutput->status = "client-error-not-authorized"; - break; - - case 0x0404: - $this->serveroutput->status = "client-error-not-possible"; - break; - - case 0x0405: - $this->serveroutput->status = "client-error-timeout"; - break; - - case 0x0406: - $this->serveroutput->status = "client-error-not-found"; - break; - - case 0x0407: - $this->serveroutput->status = "client-error-gone"; - break; - - case 0x0408: - $this->serveroutput->status = "client-error-request-entity-too-large"; - break; - - case 0x0409: - $this->serveroutput->status = "client-error-request-value-too-long"; - break; - - case 0x040A: - $this->serveroutput->status = "client-error-document-format-not-supported"; - break; - - case 0x040B: - $this->serveroutput->status = "client-error-attributes-or-values-not-supported"; - break; - - case 0x040C: - $this->serveroutput->status = "client-error-uri-scheme-not-supported"; - break; - - case 0x040D: - $this->serveroutput->status = "client-error-charset-not-supported"; - break; - - case 0x040E: - $this->serveroutput->status = "client-error-conflicting-attributes"; - break; - - case 0x040F: - $this->serveroutput->status = "client-error-compression-not-supported"; - break; - - case 0x0410: - $this->serveroutput->status = "client-error-compression-error"; - break; - - case 0x0411: - $this->serveroutput->status = "client-error-document-format-error"; - break; - - case 0x0412: - $this->serveroutput->status = "client-error-document-access-error"; - break; - - case 0x0413: // RFC3380 - $this->serveroutput->status = "client-error-attributes-not-settable"; - break; - - case 0x0500: - $this->serveroutput->status = "server-error-internal-error"; - break; - - case 0x0501: - $this->serveroutput->status = "server-error-operation-not-supported"; - break; - - case 0x0502: - $this->serveroutput->status = "server-error-service-unavailable"; - break; - - case 0x0503: - $this->serveroutput->status = "server-error-version-not-supported"; - break; - - case 0x0504: - $this->serveroutput->status = "server-error-device-error"; - break; - - case 0x0505: - $this->serveroutput->status = "server-error-temporary-error"; - break; - - case 0x0506: - $this->serveroutput->status = "server-error-not-accepting-jobs"; - break; - - case 0x0507: - $this->serveroutput->status = "server-error-busy"; - break; - - case 0x0508: - $this->serveroutput->status = "server-error-job-canceled"; - break; - - case 0x0509: - $this->serveroutput->status = "server-error-multiple-document-jobs-not-supported"; - break; - - default: - break; - } - self::_putDebug( - sprintf( - "status-code: %s%s: %s ", - $this->serveroutput->body[$this->_parsing->offset], - $this->serveroutput->body[$this->_parsing->offset + 1], - $this->serveroutput->status), - 4); - return; - } - - protected function _parseRequestID() - { - $this->serveroutput->request_id = - self::_interpretInteger( - substr($this->serveroutput->body, $this->_parsing->offset, 4) - ); - self::_putDebug("request-id " . $this->serveroutput->request_id, 2); - $this->_parsing->offset+= 4; - return; - } - - protected function _interpretInteger($value) - { - // they are _signed_ integers - $value_parsed = 0; - for ($i = strlen($value); $i > 0; $i --) - { - $value_parsed += - ( - (1 << (($i - 1) * 8)) - * - ord($value[strlen($value) - $i]) - ); - - } - if ($value_parsed >= 2147483648) - { - $value_parsed -= 4294967296; - } - return $value_parsed; - } - - protected function _parseResponse() - { - } - - // - // REQUEST BUILDING - // - - protected function _stringJob() - { - if (!isset($this->setup->charset)) self::setCharset('us-ascii'); - if (!isset($this->setup->datatype)) self::setBinary(); - if (!isset($this->setup->uri)) - { - $this->getPrinters(); - unset($this->jobs[count($this->jobs) - 1]); - unset($this->jobs_uri[count($this->jobs_uri) - 1]); - unset($this->status[count($this->status) - 1]); - if (array_key_exists(0, $this->available_printers)) - { - self::setPrinterURI($this->available_printers[0]); - } - else - { - trigger_error( - _("_stringJob: Printer URI is not set: die"), - E_USER_WARNING); - self::_putDebug(_("_stringJob: Printer URI is not set: die") , 4); - self::_errorLog(" Printer URI is not set, die", 2); - return FALSE; - } - } - if (!isset($this->setup->copies)) self::setCopies(1); - if (!isset($this->setup->language)) self::setLanguage('en_us'); - if (!isset($this->setup->mime_media_type)) self::setMimeMediaType(); - if (!isset($this->setup->jobname)) self::setJobName(); - unset($this->setup->jobname); - if (!isset($this->meta->username)) self::setUserName(); - if (!isset($this->meta->fidelity)) $this->meta->fidelity = ''; - if (!isset($this->meta->document_name)) $this->meta->document_name = ''; - if (!isset($this->meta->sides)) $this->meta->sides = ''; - if (!isset($this->meta->page_ranges)) $this->meta->page_ranges = ''; - $jobattributes = ''; - $operationattributes = ''; - $printerattributes = ''; - $this->_buildValues($operationattributes, $jobattributes, $printerattributes); - self::_setOperationId(); - if (!isset($this->error_generation->request_body_malformed)) - { - $this->error_generation->request_body_malformed = ""; - } - $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number - . chr(0x00) . chr(0x02) // Print-Job | operation-id - . $this->meta->operation_id // request-id - . chr(0x01) // start operation-attributes | operation-attributes-tag - . $this->meta->charset - . $this->meta->language - . $this->meta->printer_uri - . $this->meta->username - . $this->meta->jobname - . $this->meta->fidelity - . $this->meta->document_name - . $this->meta->mime_media_type - . $operationattributes; - if ($this->meta->copies || $this->meta->sides || $this->meta->page_ranges || !empty($jobattributes)) - { - $this->stringjob .= - chr(0x02) // start job-attributes | job-attributes-tag - . $this->meta->copies - . $this->meta->sides - . $this->meta->page_ranges - . $jobattributes - ; - } - $this->stringjob.= chr(0x03); // end-of-attributes | end-of-attributes-tag - self::_putDebug( - sprintf(_("String sent to the server is: %s"), - $this->stringjob) - ); - return TRUE; - } - - protected function _buildValues(&$operationattributes, &$jobattributes, &$printerattributes) - { - $operationattributes = ''; - foreach($this->operation_tags as $key => $values) - { - $item = 0; - if (array_key_exists('value', $values)) - { - foreach($values['value'] as $item_value) + public function setLog($log_destination, $destination_type = 'file', $level = 2) { - if ($item == 0) - { - $operationattributes .= - $values['systag'] - . self::_giveMeStringLength($key) - . $key - . self::_giveMeStringLength($item_value) - . $item_value; - } - else - { - $operationattributes .= - $values['systag'] - . self::_giveMeStringLength('') - . self::_giveMeStringLength($item_value) - . $item_value; - } - $item++; + if (!file_exists($log_destination) && is_writable(dirname($log_destination))) + { + touch($log_destination); + chmod($log_destination, 0777); + } + + switch ($destination_type) + { + case 'file': + case 3: + $this->log_destination = $log_destination; + $this->log_type = 3; + break; + + case 'logger': + case 0: + $this->log_destination = ''; + $this->log_type = 0; + break; + + case 'e-mail': + case 1: + $this->log_destination = $log_destination; + $this->log_type = 1; + break; + } + $this->log_level = $level; } - } - } - $jobattributes = ''; - foreach($this->job_tags as $key => $values) - { - $item = 0; - if (array_key_exists('value', $values)) - { - foreach($values['value'] as $item_value) + + public function printDebug() { - if ($item == 0) - { - $jobattributes .= - $values['systag'] - . self::_giveMeStringLength($key) - . $key - . self::_giveMeStringLength($item_value) - . $item_value; - } - else - { - $jobattributes .= - $values['systag'] - . self::_giveMeStringLength('') - . self::_giveMeStringLength($item_value) - . $item_value; - } - $item++; + for ($i = 0; $i < $this->debug_count; $i++) + { + echo $this->debug[$i], "\n"; + } + $this->debug = array(); + $this->debug_count = 0; } - } - } - $printerattributes = ''; - foreach($this->printer_tags as $key => $values) - { - $item = 0; - if (array_key_exists('value', $values)) - { - foreach($values['value'] as $item_value) + + public function getDebug() { - if ($item == 0) - { - $printerattributes .= - $values['systag'] - . self::_giveMeStringLength($key) - . $key - . self::_giveMeStringLength($item_value) - . $item_value; - } - else - { - $printerattributes .= - $values['systag'] - . self::_giveMeStringLength('') - . self::_giveMeStringLength($item_value) - . $item_value; - } - $item++; + $debug = ''; + for ($i = 0; $i < $this->debug_count; $i++) + { + $debug.= $this->debug[$i]; + } + $this->debug = array(); + $this->debug_count = 0; + return $debug; } - } - } - reset($this->job_tags); - reset($this->operation_tags); - reset($this->printer_tags); - return true; - } - protected function _giveMeStringLength($string) - { - $length = strlen($string); - if ($length > ((0xFF << 8) + 0xFF) ) - { - $errmsg = sprintf ( - _('max string length for an ipp meta-information = %d, while here %d'), - ((0xFF << 8) + 0xFF), $length); - - if ($this->with_exceptions) - { - throw new ippException($errmsg); - } - else - { - trigger_error ($errmsg, E_USER_ERROR); - } - } - $int1 = $length & 0xFF; - $length -= $int1; - $length = $length >> 8; - $int2 = $length & 0xFF; - return chr($int2) . chr($int1); - } - - protected function _enumBuild($tag, $value) - { - switch ($tag) - { - case "orientation-requested": - switch ($value) + // + // OPERATIONS + // + public function printJob() { - case 'portrait': - $value = chr(3); - break; - - case 'landscape': - $value = chr(4); - break; - - case 'reverse-landscape': - $value = chr(5); - break; - - case 'reverse-portrait': - $value = chr(6); - break; - } - break; - - case "print-quality": - switch ($value) - { - case 'draft': - $value = chr(3); - break; - - case 'normal': - $value = chr(4); - break; - - case 'high': - $value = chr(5); - break; - } - break; - - case "finishing": - switch ($value) - { - case 'none': - $value = chr(3); - break; - - case 'staple': - $value = chr(4); - break; - - case 'punch': - $value = chr(5); - break; - - case 'cover': - $value = chr(6); - break; - - case 'bind': - $value = chr(7); - break; - - case 'saddle-stitch': - $value = chr(8); - break; - - case 'edge-stitch': - $value = chr(9); - break; - - case 'staple-top-left': - $value = chr(20); - break; - - case 'staple-bottom-left': - $value = chr(21); - break; - - case 'staple-top-right': - $value = chr(22); - break; - - case 'staple-bottom-right': - $value = chr(23); - break; - - case 'edge-stitch-left': - $value = chr(24); - break; - - case 'edge-stitch-top': - $value = chr(25); - break; - - case 'edge-stitch-right': - $value = chr(26); - break; - - case 'edge-stitch-bottom': - $value = chr(27); - break; - - case 'staple-dual-left': - $value = chr(28); - break; - - case 'staple-dual-top': - $value = chr(29); - break; - - case 'staple-dual-right': - $value = chr(30); - break; - - case 'staple-dual-bottom': - $value = chr(31); - break; - } - break; - } - $prepend = ''; - while ((strlen($value) + strlen($prepend)) < 4) - { - $prepend .= chr(0); - } - return $prepend . $value; - } - - protected function _integerBuild($value) - { - if ($value >= 2147483647 || $value < - 2147483648) - { - trigger_error( - _("Values must be between -2147483648 and 2147483647: assuming '0'") , E_USER_WARNING); - return chr(0x00) . chr(0x00) . chr(0x00) . chr(0x00); - } - $initial_value = $value; - $int1 = $value & 0xFF; - $value -= $int1; - $value = $value >> 8; - $int2 = $value & 0xFF; - $value-= $int2; - $value = $value >> 8; - $int3 = $value & 0xFF; - $value-= $int3; - $value = $value >> 8; - $int4 = $value & 0xFF; //64bits - if ($initial_value < 0) $int4 = chr($int4) | chr(0x80); - else $int4 = chr($int4); - $value = $int4 . chr($int3) . chr($int2) . chr($int1); - return $value; - } - - protected function _rangeOfIntegerBuild($integers) - { - #$integers = split(":", $integers); - $integers = preg_split("#:#", $integers); - for ($i = 0; $i < 2; $i++) $outvalue[$i] = self::_integerBuild($integers[$i]); - return $outvalue[0] . $outvalue[1]; - } - - protected function _setJobAttribute($attribute, $value) - { - //used by setAttribute - $tag_type = $this->job_tags[$attribute]['tag']; - switch ($tag_type) - { - case 'integer': - $this->job_tags[$attribute]['value'][] = self::_integerBuild($value); - break; - - case 'nameWithoutLanguage': - case 'nameWithLanguage': - case 'textWithoutLanguage': - case 'textWithLanguage': - case 'keyword': - case 'naturalLanguage': - $this->job_tags[$attribute]['value'][] = $value; - break; - - case 'enum': - $value = $this->_enumBuild($attribute, $value); // may be overwritten by children - $this->job_tags[$attribute]['value'][] = $value; - break; - - case 'rangeOfInteger': - // $value have to be: INT1:INT2 , eg 100:1000 - $this->job_tags[$attribute]['value'][] = self::_rangeOfIntegerBuild($value); - break; - - case 'resolution': - if (preg_match("#dpi#", $value)) $unit = chr(0x3); - if (preg_match("#dpc#", $value)) $unit = chr(0x4); - $search = array( - "#(dpi|dpc)#", - '#(x|-)#' + // this BASIC version of printJob do not parse server + // output for job's attributes + self::_putDebug( + sprintf( + "************** Date: %s ***********", + date('Y-m-d H:i:s') + ) + ); + if (!$this->_stringJob()) { + return FALSE; + } + if (is_readable($this->data)) + { + self::_putDebug(_("Printing a FILE")); + $this->output = $this->stringjob; + if ($this->setup->datatype == "TEXT") + { + $this->output.= chr(0x16); + } + $post_values = array( + "Content-Type" => "application/ipp", + "Data" => $this->output, + "File" => $this->data ); - $replace = array( - "", - ":" - ); - $value = self::_rangeOfIntegerBuild(preg_replace($search, $replace, $value)) . $unit; - $this->job_tags[$attribute]['value'][] = $value; - break; + if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed)) + { + $post_values = array_merge( + $post_values, + array( + "Filetype" => "TEXT" + ) + ); + } + } + else + { + self::_putDebug(_("Printing DATA")); + $this->output = + $this->stringjob + . $this->datahead + . $this->data + . $this->datatail; + $post_values = array( + "Content-Type" => "application/ipp", + "Data" => $this->output + ); + } + if (self::_sendHttp($post_values, $this->paths["printers"])) + { + self::_parseServerOutput(); + } + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status, array( + $this->serveroutput->status + )); + if ($this->serveroutput->status == "successfull-ok") + { + self::_errorLog( + sprintf("printing job %s: ", $this->last_job) + . $this->serveroutput->status, + 3); + } + else + { + self::_errorLog( + sprintf("printing job: ", $this->last_job) + . $this->serveroutput->status, + 1); + } + return $this->serveroutput->status; + } - default: - trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); - self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - return FALSE; - break; - } - $this->job_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; - } + $this->status = + array_merge($this->status, array("OPERATION FAILED")); + $this->jobs = + array_merge($this->jobs, array("")); + $this->jobs_uri = + array_merge($this->jobs_uri, array("")); - protected function _setOperationAttribute($attribute, $value) - { - //used by setAttribute - $tag_type = $this->operation_tags[$attribute]['tag']; - switch ($tag_type) - { - case 'integer': - $this->operation_tags[$attribute]['value'][] = self::_integerBuild($value); - break; + self::_errorLog("printing job : OPERATION FAILED", 1); + return false; + } - case 'keyword': - case 'naturalLanguage': - $this->operation_tags[$attribute]['value'][] = $value; - break; + // + // HTTP OUTPUT + // + protected function _sendHttp($post_values, $uri) + { + /* + This function Copyright (C) 2005-2006 Thomas Harding, Manuel Lemos + */ + $this->response_completed[] = "no"; + unset($this->serverouptut); + self::_putDebug(_("Processing HTTP request") , 2); + $this->serveroutput->headers = array(); + $this->serveroutput->body = ""; + $http = new http_class; + if (!$this->unix) { + $http->host = $this->host; + } + else { + $http->host = "localhost"; + } + $http->with_exceptions = $this->with_exceptions; + if ($this->debug_http) + { + $http->debug = 1; + $http->html_debug = 0; + } + else + { + $http->debug = 0; + $http->html_debug = 0; + } + $url = "http://" . $this->host; + if ($this->ssl) { + $url = "https://" . $this->host; + } + if ($this->unix) { + $url = "unix://" . $this->host; + } + $http->port = $this->port; + $http->timeout = $this->http_timeout; + $http->data_timeout = $this->http_data_timeout; + $http->force_multipart_form_post = false; + $http->user = $this->username; + $http->password = $this->password; + $error = $http->GetRequestArguments($url, $arguments); + $arguments["RequestMethod"] = "POST"; + $arguments["Headers"] = array( + "Content-Type" => "application/ipp" + ); + $arguments["BodyStream"] = array( + array( + "Data" => $post_values["Data"] + ) + ); + if (isset($post_values["File"])) { + $arguments["BodyStream"][] = array( + "File" => $post_values["File"] + ); + } + if (isset($post_values["FileType"]) + && !strcmp($post_values["FileType"], "TEXT") + ) + { + $arguments["BodyStream"][] = array("Data" => Chr(12)); + } + $arguments["RequestURI"] = $uri; + if ($this->with_exceptions && $this->handle_http_exceptions) + { + try + { + $success = $http->Open($arguments); + } + catch(httpException $e) + { + throw new ippException( + sprintf("http error: %s", $e->getMessage()), + $e->getErrno()); + } + } + else + { + $success = $http->Open($arguments); + } + if ($success[0] == true) + { + $success = $http->SendRequest($arguments); + if ($success[0] == true) + { + self::_putDebug("H T T P R E Q U E S T :"); + self::_putDebug("Request headers:"); + for (Reset($http->request_headers) , $header = 0; $header < count($http->request_headers); Next($http->request_headers) , $header++) + { + $header_name = Key($http->request_headers); + if (GetType($http->request_headers[$header_name]) == "array") + { + for ($header_value = 0; $header_value < count($http->request_headers[$header_name]); $header_value++) + { + self::_putDebug($header_name . ": " . $http->request_headers[$header_name][$header_value]); + } + } + else + { + self::_putDebug($header_name . ": " . $http->request_headers[$header_name]); + } + } + self::_putDebug("Request body:"); + self::_putDebug( + htmlspecialchars($http->request_body) + . "*********** END REQUEST BODY *********" + ); + $i = 0; + $headers = array(); + unset($this->serveroutput->headers); + $http->ReadReplyHeaders($headers); + self::_putDebug("H T T P R E S P O N S E :"); + self::_putDebug("Response headers:"); + for (Reset($headers) , $header = 0; $header < count($headers); Next($headers) , $header++) + { + $header_name = Key($headers); + if (GetType($headers[$header_name]) == "array") + { + for ($header_value = 0; $header_value < count($headers[$header_name]); $header_value++) + { + self::_putDebug($header_name . ": " . $headers[$header_name][$header_value]); + $this->serveroutput->headers[$i] = + $header_name . ": " + . $headers[$header_name][$header_value]; + $i++; + } + } + else + { + self::_putDebug($header_name . ": " . $headers[$header_name]); + $this->serveroutput->headers[$i] = + $header_name + . ": " + . $headers[$header_name]; + $i++; + } + } + self::_putDebug("\n\nResponse body:\n"); + $this->serveroutput->body = ""; + for (;;) + { + $http->ReadReplyBody($body, 1024); + if (strlen($body) == 0) { + break; + } - default: - trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); - self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - return FALSE; - break; - } - $this->operation_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; - } + self::_putDebug(htmlentities($body)); + $this->serveroutput->body.= $body; + } + self::_putDebug("********* END RESPONSE BODY ********"); + } + } + $http->Close(); + return true; + } - protected function _setPrinterAttribute($attribute, $value) - { - //used by setAttribute - $tag_type = $this->printer_tags[$attribute]['tag']; - switch ($tag_type) - { - case 'integer': - $this->printer_tags[$attribute]['value'][] = self::_integerBuild($value); - break; + // + // INIT + // + protected function _initTags() + { + $this->tags_types = array( + "unsupported" => array( + "tag" => chr(0x10) , + "build" => "" + ) , + "reserved" => array( + "tag" => chr(0x11) , + "build" => "" + ) , + "unknown" => array( + "tag" => chr(0x12) , + "build" => "" + ) , + "no-value" => array( + "tag" => chr(0x13) , + "build" => "no_value" + ) , + "integer" => array( + "tag" => chr(0x21) , + "build" => "integer" + ) , + "boolean" => array( + "tag" => chr(0x22) , + "build" => "boolean" + ) , + "enum" => array( + "tag" => chr(0x23) , + "build" => "enum" + ) , + "octetString" => array( + "tag" => chr(0x30) , + "build" => "octet_string" + ) , + "datetime" => array( + "tag" => chr(0x31) , + "build" => "datetime" + ) , + "resolution" => array( + "tag" => chr(0x32) , + "build" => "resolution" + ) , + "rangeOfInteger" => array( + "tag" => chr(0x33) , + "build" => "range_of_integers" + ) , + "textWithLanguage" => array( + "tag" => chr(0x35) , + "build" => "string" + ) , + "nameWithLanguage" => array( + "tag" => chr(0x36) , + "build" => "string" + ) , + /* + "text" => array ("tag" => chr(0x40), + "build" => "string"), + "text string" => array ("tag" => chr(0x40), + "build" => "string"), + */ + "textWithoutLanguage" => array( + "tag" => chr(0x41) , + "build" => "string" + ) , + "nameWithoutLanguage" => array( + "tag" => chr(0x42) , + "buid" => "string" + ) , + "keyword" => array( + "tag" => chr(0x44) , + "build" => "string" + ) , + "uri" => array( + "tag" => chr(0x45) , + "build" => "string" + ) , + "uriScheme" => array( + "tag" => chr(0x46) , + "build" => "string" + ) , + "charset" => array( + "tag" => chr(0x47) , + "build" => "string" + ) , + "naturalLanguage" => array( + "tag" => chr(0x48) , + "build" => "string" + ) , + "mimeMediaType" => array( + "tag" => chr(0x49) , + "build" => "string" + ) , + "extendedAttributes" => array( + "tag" => chr(0x7F) , + "build" => "extended" + ) , + ); + $this->operation_tags = array( + "compression" => array( + "tag" => "keyword" + ) , + "document-natural-language" => array( + "tag" => "naturalLanguage" + ) , + "job-k-octets" => array( + "tag" => "integer" + ) , + "job-impressions" => array( + "tag" => "integer" + ) , + "job-media-sheets" => array( + "tag" => "integer" + ) , + ); + $this->job_tags = array( + "job-priority" => array( + "tag" => "integer" + ) , + "job-hold-until" => array( + "tag" => "keyword" + ) , + "job-sheets" => array( + "tag" => "keyword" + ) , //banner page + "multiple-document-handling" => array( + "tag" => "keyword" + ) , + //"copies" => array("tag" => "integer"), + "finishings" => array( + "tag" => "enum" + ) , + //"page-ranges" => array("tag" => "rangeOfInteger"), // has its own function + //"sides" => array("tag" => "keyword"), // has its own function + "number-up" => array( + "tag" => "integer" + ) , + "orientation-requested" => array( + "tag" => "enum" + ) , + "media" => array( + "tag" => "keyword" + ) , + "printer-resolution" => array( + "tag" => "resolution" + ) , + "print-quality" => array( + "tag" => "enum" + ) , + "job-message-from-operator" => array( + "tag" => "textWithoutLanguage" + ) , + ); + $this->printer_tags = array( + "requested-attributes" => array( + "tag" => "keyword" + ) + ); + } - case 'keyword': - case 'naturalLanguage': - $this->printer_tags[$attribute]['value'][] = $value; - break; + // + // SETUP + // + protected function _setOperationId() + { + $prepend = ''; + $this->operation_id+= 1; + $this->meta->operation_id = self::_integerBuild($this->operation_id); + self::_putDebug("operation id is: " . $this->operation_id, 2); + } - default: - trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); - self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - return FALSE; - break; - } - $this->printer_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; - } + protected function _setJobId() + { + $this->meta->jobid+= 1; + $prepend = ''; + $prepend_length = 4 - strlen($this->meta->jobid); + for ($i = 0; $i < $prepend_length; $i++) { + $prepend.= '0'; + } + return $prepend . $this->meta->jobid; + } - // - // DEBUGGING - // - protected function _putDebug($string, $level = 1) - { - if ($level === false) return; - if ($level < $this->debug_level) return; - $this->debug[$this->debug_count] = substr($string, 0, 1024); - $this->debug_count++; - //$this->debug .= substr($string,0,1024); + protected function _setJobUri($job_uri) + { + $this->meta->job_uri = chr(0x45) // type uri + . chr(0x00) . chr(0x07) // name-length + . "job-uri" + //. chr(0x00).chr(strlen($job_uri)) + . self::_giveMeStringLength($job_uri) . $job_uri; + self::_putDebug("job-uri is: " . $job_uri, 2); + } - } + // + // RESPONSE PARSING + // + protected function _parseServerOutput() + { + $this->serveroutput->response = array(); + if (!self::_parseHttpHeaders()) { + return FALSE; + } + $this->_parsing->offset = 0; + self::_parseIppVersion(); + self::_parseStatusCode(); + self::_parseRequestID(); + $this->_parseResponse(); + //devel + self::_putDebug( + sprintf("***** IPP STATUS: %s ******", $this->serveroutput->status), + 4); + self::_putDebug("****** END OF OPERATION ****"); + return true; + } - // - // LOGGING - // - protected function _errorLog($string_to_log, $level) - { - if ($level < $this->log_level) return; - $string = sprintf('%s : %s:%s user %s : %s', basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log); - if ($this->log_type == 0) - { - error_log($string); - return; - } - $string = sprintf("%s %s Host %s:%s user %s : %s\n", date('M d H:i:s') , basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log); - error_log($string, $this->log_type, $this->log_destination); - return; - } + protected function _parseHttpHeaders() + { + $response = ""; + switch ($this->serveroutput->headers[0]) + { + case "http/1.1 200 ok: ": + $this->serveroutput->httpstatus = "HTTP/1.1 200 OK"; + $response = "OK"; + break; -}; -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ -?> + // primitive http/1.0 for Lexmark printers (from Rick Baril) + case "http/1.0 200 ok: ": + $this->serveroutput->httpstatus = "HTTP/1.0 200 OK"; + $response = "OK"; + break; + + case "http/1.1 100 continue: ": + $this->serveroutput->httpstatus = "HTTP/1.1 100 CONTINUE"; + $response = "OK"; + break; + + case "": + $this->serveroutput->httpstatus = "HTTP/1.1 000 No Response From Server"; + $this->serveroutput->status = "HTTP-ERROR-000_NO_RESPONSE_FROM_SERVER"; + trigger_error("No Response From Server", E_USER_WARNING); + self::_errorLog("No Response From Server", 1); + $this->disconnected = 1; + return FALSE; + break; + + default: + $server_response = preg_replace("/: $/", '', $this->serveroutput->headers[0]); + #$strings = split(' ', $server_response, 3); + $strings = preg_split('# #', $server_response, 3); + $errno = $strings[1]; + $string = strtoupper(str_replace(' ', '_', $strings[2])); + trigger_error( + sprintf(_("server responds %s") , $server_response), + E_USER_WARNING); + self::_errorLog("server responds " . $server_response, 1); + $this->serveroutput->httpstatus = + strtoupper($strings[0]) + . " " + . $errno + . " " + . ucfirst($strings[2]); + + $this->serveroutput->status = + "HTTP-ERROR-" + . $errno + . "-" + . $string; + $this->disconnected = 1; + return FALSE; + break; + } + unset($this->serveroutput->headers); + return TRUE; + } + + protected function _parseIppVersion() + { + $ippversion = + (ord($this->serveroutput->body[$this->_parsing->offset]) * 256) + + ord($this->serveroutput->body[$this->_parsing->offset + 1]); + switch ($ippversion) + { + case 0x0101: + $this->serveroutput->ipp_version = "1.1"; + break; + + default: + $this->serveroutput->ipp_version = + sprintf("%u.%u (Unknown)", + ord($this->serveroutput->body[$this->_parsing->offset]) * 256, + ord($this->serveroutput->body[$this->_parsing->offset + 1])); + break; + } + self::_putDebug("I P P R E S P O N S E :\n\n"); + self::_putDebug( + sprintf("IPP version %s%s: %s", + ord($this->serveroutput->body[$this->_parsing->offset]), + ord($this->serveroutput->body[$this->_parsing->offset + 1]), + $this->serveroutput->ipp_version)); + $this->_parsing->offset+= 2; + return; + } + + protected function _parseStatusCode() + { + $status_code = + (ord($this->serveroutput->body[$this->_parsing->offset]) * 256) + + ord($this->serveroutput->body[$this->_parsing->offset + 1]); + $this->serveroutput->status = "NOT PARSED"; + $this->_parsing->offset+= 2; + if (strlen($this->serveroutput->body) < $this->_parsing->offset) + { + return false; + } + if ($status_code < 0x00FF) + { + $this->serveroutput->status = "successfull"; + } + elseif ($status_code < 0x01FF) + { + $this->serveroutput->status = "informational"; + } + elseif ($status_code < 0x02FF) + { + $this->serveroutput->status = "redirection"; + } + elseif ($status_code < 0x04FF) + { + $this->serveroutput->status = "client-error"; + } + elseif ($status_code < 0x05FF) + { + $this->serveroutput->status = "server-error"; + } + switch ($status_code) + { + case 0x0000: + $this->serveroutput->status = "successfull-ok"; + break; + + case 0x0001: + $this->serveroutput->status = "successful-ok-ignored-or-substituted-attributes"; + break; + + case 0x002: + $this->serveroutput->status = "successful-ok-conflicting-attributes"; + break; + + case 0x0400: + $this->serveroutput->status = "client-error-bad-request"; + break; + + case 0x0401: + $this->serveroutput->status = "client-error-forbidden"; + break; + + case 0x0402: + $this->serveroutput->status = "client-error-not-authenticated"; + break; + + case 0x0403: + $this->serveroutput->status = "client-error-not-authorized"; + break; + + case 0x0404: + $this->serveroutput->status = "client-error-not-possible"; + break; + + case 0x0405: + $this->serveroutput->status = "client-error-timeout"; + break; + + case 0x0406: + $this->serveroutput->status = "client-error-not-found"; + break; + + case 0x0407: + $this->serveroutput->status = "client-error-gone"; + break; + + case 0x0408: + $this->serveroutput->status = "client-error-request-entity-too-large"; + break; + + case 0x0409: + $this->serveroutput->status = "client-error-request-value-too-long"; + break; + + case 0x040A: + $this->serveroutput->status = "client-error-document-format-not-supported"; + break; + + case 0x040B: + $this->serveroutput->status = "client-error-attributes-or-values-not-supported"; + break; + + case 0x040C: + $this->serveroutput->status = "client-error-uri-scheme-not-supported"; + break; + + case 0x040D: + $this->serveroutput->status = "client-error-charset-not-supported"; + break; + + case 0x040E: + $this->serveroutput->status = "client-error-conflicting-attributes"; + break; + + case 0x040F: + $this->serveroutput->status = "client-error-compression-not-supported"; + break; + + case 0x0410: + $this->serveroutput->status = "client-error-compression-error"; + break; + + case 0x0411: + $this->serveroutput->status = "client-error-document-format-error"; + break; + + case 0x0412: + $this->serveroutput->status = "client-error-document-access-error"; + break; + + case 0x0413: // RFC3380 + $this->serveroutput->status = "client-error-attributes-not-settable"; + break; + + case 0x0500: + $this->serveroutput->status = "server-error-internal-error"; + break; + + case 0x0501: + $this->serveroutput->status = "server-error-operation-not-supported"; + break; + + case 0x0502: + $this->serveroutput->status = "server-error-service-unavailable"; + break; + + case 0x0503: + $this->serveroutput->status = "server-error-version-not-supported"; + break; + + case 0x0504: + $this->serveroutput->status = "server-error-device-error"; + break; + + case 0x0505: + $this->serveroutput->status = "server-error-temporary-error"; + break; + + case 0x0506: + $this->serveroutput->status = "server-error-not-accepting-jobs"; + break; + + case 0x0507: + $this->serveroutput->status = "server-error-busy"; + break; + + case 0x0508: + $this->serveroutput->status = "server-error-job-canceled"; + break; + + case 0x0509: + $this->serveroutput->status = "server-error-multiple-document-jobs-not-supported"; + break; + + default: + break; + } + self::_putDebug( + sprintf( + "status-code: %s%s: %s ", + $this->serveroutput->body[$this->_parsing->offset], + $this->serveroutput->body[$this->_parsing->offset + 1], + $this->serveroutput->status), + 4); + return; + } + + protected function _parseRequestID() + { + $this->serveroutput->request_id = + self::_interpretInteger( + substr($this->serveroutput->body, $this->_parsing->offset, 4) + ); + self::_putDebug("request-id " . $this->serveroutput->request_id, 2); + $this->_parsing->offset+= 4; + return; + } + + protected function _interpretInteger($value) + { + // they are _signed_ integers + $value_parsed = 0; + for ($i = strlen($value); $i > 0; $i --) + { + $value_parsed += + ( + (1 << (($i - 1) * 8)) + * + ord($value[strlen($value) - $i]) + ); + } + if ($value_parsed >= 2147483648) + { + $value_parsed -= 4294967296; + } + return $value_parsed; + } + + protected function _parseResponse() + { + } + + // + // REQUEST BUILDING + // + protected function _stringJob() + { + if (!isset($this->setup->charset)) { + self::setCharset(); + } + if (!isset($this->setup->datatype)) { + self::setBinary(); + } + if (!isset($this->setup->uri)) + { + $this->getPrinters(); + unset($this->jobs[count($this->jobs) - 1]); + unset($this->jobs_uri[count($this->jobs_uri) - 1]); + unset($this->status[count($this->status) - 1]); + if (array_key_exists(0, $this->available_printers)) + { + self::setPrinterURI($this->available_printers[0]); + } + else + { + trigger_error( + _("_stringJob: Printer URI is not set: die"), + E_USER_WARNING); + self::_putDebug(_("_stringJob: Printer URI is not set: die") , 4); + self::_errorLog(" Printer URI is not set, die", 2); + return FALSE; + } + } + if (!isset($this->setup->copies)) { + self::setCopies(1); + } + if (!isset($this->setup->language)) { + self::setLanguage('en_us'); + } + if (!isset($this->setup->mime_media_type)) { + self::setMimeMediaType(); + } + if (!isset($this->setup->jobname)) { + self::setJobName(); + } + unset($this->setup->jobname); + if (!isset($this->meta->username)) { + self::setUserName(); + } + if (!isset($this->meta->fidelity)) { + $this->meta->fidelity = ''; + } + if (!isset($this->meta->document_name)) { + $this->meta->document_name = ''; + } + if (!isset($this->meta->sides)) { + $this->meta->sides = ''; + } + if (!isset($this->meta->page_ranges)) { + $this->meta->page_ranges = ''; + } + $jobattributes = ''; + $operationattributes = ''; + $printerattributes = ''; + $this->_buildValues($operationattributes, $jobattributes, $printerattributes); + self::_setOperationId(); + if (!isset($this->error_generation->request_body_malformed)) + { + $this->error_generation->request_body_malformed = ""; + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number + . chr(0x00) . chr(0x02) // Print-Job | operation-id + . $this->meta->operation_id // request-id + . chr(0x01) // start operation-attributes | operation-attributes-tag + . $this->meta->charset + . $this->meta->language + . $this->meta->printer_uri + . $this->meta->username + . $this->meta->jobname + . $this->meta->fidelity + . $this->meta->document_name + . $this->meta->mime_media_type + . $operationattributes; + if ($this->meta->copies || $this->meta->sides || $this->meta->page_ranges || !empty($jobattributes)) + { + $this->stringjob .= + chr(0x02) // start job-attributes | job-attributes-tag + . $this->meta->copies + . $this->meta->sides + . $this->meta->page_ranges + . $jobattributes; + } + $this->stringjob.= chr(0x03); // end-of-attributes | end-of-attributes-tag + self::_putDebug( + sprintf(_("String sent to the server is: %s"), + $this->stringjob) + ); + return TRUE; + } + + protected function _buildValues(&$operationattributes, &$jobattributes, &$printerattributes) + { + $operationattributes = ''; + foreach($this->operation_tags as $key => $values) + { + $item = 0; + if (array_key_exists('value', $values)) + { + foreach($values['value'] as $item_value) + { + if ($item == 0) + { + $operationattributes .= + $values['systag'] + . self::_giveMeStringLength($key) + . $key + . self::_giveMeStringLength($item_value) + . $item_value; + } + else + { + $operationattributes .= + $values['systag'] + . self::_giveMeStringLength('') + . self::_giveMeStringLength($item_value) + . $item_value; + } + $item++; + } + } + } + $jobattributes = ''; + foreach($this->job_tags as $key => $values) + { + $item = 0; + if (array_key_exists('value', $values)) + { + foreach($values['value'] as $item_value) + { + if ($item == 0) + { + $jobattributes .= + $values['systag'] + . self::_giveMeStringLength($key) + . $key + . self::_giveMeStringLength($item_value) + . $item_value; + } + else + { + $jobattributes .= + $values['systag'] + . self::_giveMeStringLength('') + . self::_giveMeStringLength($item_value) + . $item_value; + } + $item++; + } + } + } + $printerattributes = ''; + foreach($this->printer_tags as $key => $values) + { + $item = 0; + if (array_key_exists('value', $values)) + { + foreach($values['value'] as $item_value) + { + if ($item == 0) + { + $printerattributes .= + $values['systag'] + . self::_giveMeStringLength($key) + . $key + . self::_giveMeStringLength($item_value) + . $item_value; + } + else + { + $printerattributes .= + $values['systag'] + . self::_giveMeStringLength('') + . self::_giveMeStringLength($item_value) + . $item_value; + } + $item++; + } + } + } + reset($this->job_tags); + reset($this->operation_tags); + reset($this->printer_tags); + return true; + } + + protected function _giveMeStringLength($string) + { + $length = strlen($string); + if ($length > ((0xFF << 8) + 0xFF) ) + { + $errmsg = sprintf ( + _('max string length for an ipp meta-information = %d, while here %d'), + ((0xFF << 8) + 0xFF), $length); + + if ($this->with_exceptions) + { + throw new ippException($errmsg); + } + else + { + trigger_error ($errmsg, E_USER_ERROR); + } + } + $int1 = $length & 0xFF; + $length -= $int1; + $length = $length >> 8; + $int2 = $length & 0xFF; + return chr($int2) . chr($int1); + } + + protected function _enumBuild($tag, $value) + { + switch ($tag) + { + case "orientation-requested": + switch ($value) + { + case 'portrait': + $value = chr(3); + break; + + case 'landscape': + $value = chr(4); + break; + + case 'reverse-landscape': + $value = chr(5); + break; + + case 'reverse-portrait': + $value = chr(6); + break; + } + break; + + case "print-quality": + switch ($value) + { + case 'draft': + $value = chr(3); + break; + + case 'normal': + $value = chr(4); + break; + + case 'high': + $value = chr(5); + break; + } + break; + + case "finishing": + switch ($value) + { + case 'none': + $value = chr(3); + break; + + case 'staple': + $value = chr(4); + break; + + case 'punch': + $value = chr(5); + break; + + case 'cover': + $value = chr(6); + break; + + case 'bind': + $value = chr(7); + break; + + case 'saddle-stitch': + $value = chr(8); + break; + + case 'edge-stitch': + $value = chr(9); + break; + + case 'staple-top-left': + $value = chr(20); + break; + + case 'staple-bottom-left': + $value = chr(21); + break; + + case 'staple-top-right': + $value = chr(22); + break; + + case 'staple-bottom-right': + $value = chr(23); + break; + + case 'edge-stitch-left': + $value = chr(24); + break; + + case 'edge-stitch-top': + $value = chr(25); + break; + + case 'edge-stitch-right': + $value = chr(26); + break; + + case 'edge-stitch-bottom': + $value = chr(27); + break; + + case 'staple-dual-left': + $value = chr(28); + break; + + case 'staple-dual-top': + $value = chr(29); + break; + + case 'staple-dual-right': + $value = chr(30); + break; + + case 'staple-dual-bottom': + $value = chr(31); + break; + } + break; + } + $prepend = ''; + while ((strlen($value) + strlen($prepend)) < 4) + { + $prepend .= chr(0); + } + return $prepend . $value; + } + + protected function _integerBuild($value) + { + if ($value >= 2147483647 || $value < - 2147483648) + { + trigger_error( + _("Values must be between -2147483648 and 2147483647: assuming '0'") , E_USER_WARNING); + return chr(0x00) . chr(0x00) . chr(0x00) . chr(0x00); + } + $initial_value = $value; + $int1 = $value & 0xFF; + $value -= $int1; + $value = $value >> 8; + $int2 = $value & 0xFF; + $value-= $int2; + $value = $value >> 8; + $int3 = $value & 0xFF; + $value-= $int3; + $value = $value >> 8; + $int4 = $value & 0xFF; //64bits + if ($initial_value < 0) { + $int4 = chr($int4) | chr(0x80); + } + else { + $int4 = chr($int4); + } + $value = $int4 . chr($int3) . chr($int2) . chr($int1); + return $value; + } + + protected function _rangeOfIntegerBuild($integers) + { + #$integers = split(":", $integers); + $integers = preg_split("#:#", $integers); + for ($i = 0; $i < 2; $i++) { + $outvalue[$i] = self::_integerBuild($integers[$i]); + } + return $outvalue[0] . $outvalue[1]; + } + + protected function _setJobAttribute($attribute, $value) + { + //used by setAttribute + $tag_type = $this->job_tags[$attribute]['tag']; + switch ($tag_type) + { + case 'integer': + $this->job_tags[$attribute]['value'][] = self::_integerBuild($value); + break; + + case 'boolean': + case 'nameWithoutLanguage': + case 'nameWithLanguage': + case 'textWithoutLanguage': + case 'textWithLanguage': + case 'keyword': + case 'naturalLanguage': + $this->job_tags[$attribute]['value'][] = $value; + break; + + case 'enum': + $value = $this->_enumBuild($attribute, $value); // may be overwritten by children + $this->job_tags[$attribute]['value'][] = $value; + break; + + case 'rangeOfInteger': + // $value have to be: INT1:INT2 , eg 100:1000 + $this->job_tags[$attribute]['value'][] = self::_rangeOfIntegerBuild($value); + break; + + case 'resolution': + if (preg_match("#dpi#", $value)) { + $unit = chr(0x3); + } + if (preg_match("#dpc#", $value)) { + $unit = chr(0x4); + } + $search = array( + "#(dpi|dpc)#", + '#(x|-)#' + ); + $replace = array( + "", + ":" + ); + $value = self::_rangeOfIntegerBuild(preg_replace($search, $replace, $value)) . $unit; + $this->job_tags[$attribute]['value'][] = $value; + break; + + default: + trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); + self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + return FALSE; + break; + } + $this->job_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; + } + + protected function _setOperationAttribute($attribute, $value) + { + //used by setAttribute + $tag_type = $this->operation_tags[$attribute]['tag']; + switch ($tag_type) + { + case 'integer': + $this->operation_tags[$attribute]['value'][] = self::_integerBuild($value); + break; + + case 'keyword': + case 'naturalLanguage': + $this->operation_tags[$attribute]['value'][] = $value; + break; + + default: + trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); + self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + return FALSE; + break; + } + $this->operation_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; + } + + protected function _setPrinterAttribute($attribute, $value) + { + //used by setAttribute + $tag_type = $this->printer_tags[$attribute]['tag']; + switch ($tag_type) + { + case 'integer': + $this->printer_tags[$attribute]['value'][] = self::_integerBuild($value); + break; + + case 'keyword': + case 'naturalLanguage': + $this->printer_tags[$attribute]['value'][] = $value; + break; + + default: + trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); + self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + return FALSE; + break; + } + $this->printer_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; + } + + // + // DEBUGGING + // + protected function _putDebug($string, $level = 1) + { + if ($level === false) { + return; + } + + if ($level < $this->debug_level) { + return; + } + + $this->debug[$this->debug_count] = substr($string, 0, 1024); + $this->debug_count++; + //$this->debug .= substr($string,0,1024); + + } + + // + // LOGGING + // + protected function _errorLog($string_to_log, $level) + { + if ($level > $this->log_level) { + return; + } + + $string = sprintf('%s : %s:%s user %s : %s', basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log); + + if ($this->log_type == 0) + { + error_log($string); + return; + } + + $string = sprintf("%s %s Host %s:%s user %s : %s\n", date('M d H:i:s') , basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log); + error_log($string, $this->log_type, $this->log_destination); + return; + } +} diff --git a/htdocs/includes/printipp/CupsPrintIPP.php b/htdocs/includes/printipp/CupsPrintIPP.php index a7e5a305da5..7808c64a722 100644 --- a/htdocs/includes/printipp/CupsPrintIPP.php +++ b/htdocs/includes/printipp/CupsPrintIPP.php @@ -1,5 +1,5 @@ jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en'); - + } + self::_setOperationId(); - + for($i = 0 ; $i < count($attributes) ; $i++) + { if ($i == 0) + { $this->meta->attributes = chr(0x44) // Keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' . self::_giveMeStringLength($attributes[0]) . $attributes[0]; + } else + { $this->meta->attributes .= chr(0x44) // Keyword . chr(0x0).chr(0x0) // zero-length name . self::_giveMeStringLength($attributes[$i]) . $attributes[$i]; - - $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 + } + } + + $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 . chr(0x40). chr(0x01) // operation: cups vendor extension: get defaults . $this->meta->operation_id // request-id . chr(0x01) // start operation-attributes | operation-attributes-tag @@ -97,69 +103,83 @@ class CupsPrintIPP extends ExtendedPrintIPP { . $this->meta->language . $this->meta->attributes . chr(0x03); // end operations attribute - + $this->output = $this->stringjob; - + self::_putDebug("Request: ".$this->output); - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,'/')) { - + + if (self::_sendHttp ($post_values,'/')) + { + if(self::_parseServerOutput()) + { self::_parsePrinterAttributes(); } - + } + $this->attributes = &$this->printer_attributes; - - if (isset($this->printer_attributes->printer_type)) { + + if (isset($this->printer_attributes->printer_type)) + { $printer_type = $this->printer_attributes->printer_type->_value0; $table = self::_interpretPrinterType($printer_type); - - for($i = 0 ; $i < count($table) ; $i++ ) { + + for($i = 0 ; $i < count($table) ; $i++ ) + { $index = '_value'.$i; $this->printer_attributes->printer_type->$index = $table[$i]; } - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("getting defaults: ".$this->serveroutput->status,3); + } else + { self::_errorLog("getting defaults: ".$this->serveroutput->status,1); - - return $this->serveroutput->status; - - } else { + } + + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting defaults : OPERATION FAILED",1); } - return false; + return false; } - // }}} - - // {{{ cupsAcceptJobs ($printer_uri) - public function cupsAcceptJobs($printer_uri) { + + + public function cupsAcceptJobs($printer_uri) + { //The CUPS-Get-Default operation returns the default printer URI and attributes - + $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en'); - + } + self::_setOperationId(); - - $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 + + $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 . chr(0x40). chr(0x08) // operation: cups vendor extension: Accept-Jobs . $this->meta->operation_id // request-id . chr(0x01) // start operation-attributes | operation-attributes-tag @@ -171,65 +191,80 @@ class CupsPrintIPP extends ExtendedPrintIPP { . self::_giveMeStringLength($printer_uri) . $printer_uri . chr(0x03); // end operations attribute - + $this->output = $this->stringjob; - + self::_putDebug("Request: ".$this->output); - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,'/admin/')) { - + + if (self::_sendHttp ($post_values,'/admin/')) + { + if(self::_parseServerOutput()) + { self::_parseAttributes(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("getting defaults: ".$this->serveroutput->status,3); + } else + { self::_errorLog("getting defaults: ".$this->serveroutput->status,1); - - return $this->serveroutput->status; - - } else { + } + + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting defaults : OPERATION FAILED",1); } - return false; + return false; } - // }}} - // {{{ cupsRejectJobs ($printer_uri,$printer_state_message=false) - public function cupsRejectJobs($printer_uri,$printer_state_message) { + + public function cupsRejectJobs($printer_uri,$printer_state_message) + { //The CUPS-Get-Default operation returns the default printer URI and attributes - + $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); $this->parsed = array(); unset($this->attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en'); - + } + self::_setOperationId(); - + $message = ""; if ($printer_state_message) + { $message = chr(0x04) // start printer-attributes . chr(0x41) // textWithoutLanguage . self::_giveMeStringLength("printer-state-message") . "printer-state-message" . self::_giveMeStringLength($printer_state_message) . $printer_state_message; + } - $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 + $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 . chr(0x40). chr(0x09) // operation: cups vendor extension: Reject-Jobs . $this->meta->operation_id // request-id . chr(0x01) // start operation-attributes | operation-attributes-tag @@ -242,89 +277,111 @@ class CupsPrintIPP extends ExtendedPrintIPP { . $printer_uri . $message . chr(0x03); // end operations attribute - + $this->output = $this->stringjob; - + self::_putDebug("Request: ".$this->output); - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,'/admin/')) { - + + if (self::_sendHttp ($post_values,'/admin/')) + { + if(self::_parseServerOutput()) + { self::_parseAttributes(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("getting defaults: ".$this->serveroutput->status,3); + } else + { self::_errorLog("getting defaults: ".$this->serveroutput->status,1); - - return $this->serveroutput->status; - - } else { + } + + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting defaults : OPERATION FAILED",1); - } - return false; + } + return false; } - // }}} - // {{{ getPrinters() - public function getPrinters($printer_location=false,$printer_info=false,$attributes=array()) { - + + public function getPrinters($printer_location=false,$printer_info=false,$attributes=array()) + { if (count($attributes) == 0) - true; - $attributes=array('printer-uri-supported','printer-location','printer-info','printer-type','color-supported'); + { + true; + } + $attributes=array('printer-uri-supported', 'printer-location', 'printer-info', 'printer-type', 'color-supported', 'printer-name'); $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - + unset ($this->printers_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en-us'); - + } + self::_setOperationId(); - + $this->meta->attributes=''; - + if ($printer_location) + { $this->meta->attributes .= chr(0x41) // textWithoutLanguage . self::_giveMeStringLength('printer-location') . 'printer-location' . self::_giveMeStringLength($printer_location) . $printer_location; - - + } + if ($printer_info) + { $this->meta->attributes .= chr(0x41) // textWithoutLanguage . self::_giveMeStringLength('printer-info') . 'printer-info' . self::_giveMeStringLength($printer_info) . $printer_info; - + } + for($i = 0 ; $i < count($attributes) ; $i++) + { if ($i == 0) + { $this->meta->attributes .= chr(0x44) // Keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' . self::_giveMeStringLength($attributes[0]) . $attributes[0]; + } else + { $this->meta->attributes .= chr(0x44) // Keyword . chr(0x0).chr(0x0) // zero-length name . self::_giveMeStringLength($attributes[$i]) . $attributes[$i]; + } + } - - $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 + $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 . chr(0x40). chr(0x02) // operation: cups vendor extension: get printers . $this->meta->operation_id // request-id . chr(0x01) // start operation-attributes | operation-attributes-tag @@ -332,78 +389,89 @@ class CupsPrintIPP extends ExtendedPrintIPP { . $this->meta->language . $this->meta->attributes . chr(0x03); // end operations attribute - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,'/')) { - - if(self::_parseServerOutput()) - $this->_getAvailablePrinters(); + if (self::_sendHttp ($post_values,'/')) + { + + if(self::_parseServerOutput()) + { + $this->_getAvailablePrinters(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("getting printers: ".$this->serveroutput->status,3); + } else + { self::_errorLog("getting printers: ".$this->serveroutput->status,1); - return $this->serveroutput->status; - - } else { + } + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting printers : OPERATION FAILED",1); - } - return false; + } + return false; } - // }}} - // {{{ cupsGetPrinters () - public function cupsGetPrinters () { - // alias for getPrinters(); + + public function cupsGetPrinters () + { + // alias for getPrinters(); self::getPrinters(); } - // }}} - // {{{ getPrinterAttributes() - public function getPrinterAttributes() { - // complete informations from parent with Cups-specific stuff - + + public function getPrinterAttributes() + { + // complete informations from parent with Cups-specific stuff + if(!$result = parent::getPrinterAttributes()) + { return FALSE; + } if(!isset($this->printer_attributes)) + { return FALSE; - - if (isset ($this->printer_attributes->printer_type)) { + } + + if (isset ($this->printer_attributes->printer_type)) + { $printer_type = $this->printer_attributes->printer_type->_value0; $table = self::_interpretPrinterType($printer_type); - - for($i = 0 ; $i < count($table) ; $i++ ) { + + for($i = 0 ; $i < count($table) ; $i++ ) + { $index = '_value'.$i; $this->printer_attributes->printer_type->$index = $table[$i]; - } } + } - return $result; + return $result; } - // }}} // // SETUP // - - // {{{ _initTags () - protected function _initTags () { - + protected function _initTags () + { // override parent with specific cups attributes - - $operation_tags = array (); + + $operation_tags = array (); $this->operation_tags = array_merge ($this->operation_tags, $operation_tags); - + $job_tags = array ( "job-billing" => array("tag" => "textWithoutLanguage"), "blackplot" => array("tag" => "boolean"), "brightness" => array("tag" => "integer"), @@ -430,25 +498,23 @@ class CupsPrintIPP extends ExtendedPrintIPP { "saturation" => array("tag" => "integer"), "scaling" => array("tag" => "integer"), "wrap" => array("tag","boolean"), - + ); $this->job_tags = array_merge ($this->job_tags, $job_tags); } - // }}} -// -// REQUEST BUILDING -// - - // {{{ _enumBuild ($tag,$value) - protected function _enumBuild ($tag,$value) { - + // + // REQUEST BUILDING + // + protected function _enumBuild ($tag,$value) + { $value_built = parent::_enumBuild($tag,$value); - - switch ($tag) { - case "cpi": - switch ($value) { + switch ($tag) + { + case "cpi": + switch ($value) + { case '10': $value_built = chr(10); break; @@ -463,7 +529,8 @@ class CupsPrintIPP extends ExtendedPrintIPP { } break; case "lpi": - switch ($value) { + switch ($value) + { case '6': $value_built = chr(6); break; @@ -479,60 +546,66 @@ class CupsPrintIPP extends ExtendedPrintIPP { $prepend = ''; while ((strlen($value_built) + strlen($prepend)) < 4) $prepend .= chr(0); - return $prepend.$value_built; + return $prepend.$value_built; } - // }}} - -// -// RESPONSE PARSING -// - // {{{ _getAvailablePrinters () - private function _getAvailablePrinters () { - + // + // RESPONSE PARSING + // + private function _getAvailablePrinters () + { $this->available_printers = array(); + $this->printer_map = array(); $k = 0; - $this->printers_attributes = new stdClass(); + $this->printers_attributes = new \stdClass(); for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++) - if (($this->serveroutput->response[$i]['attributes']) == "printer-attributes") { + { + if (($this->serveroutput->response[$i]['attributes']) == "printer-attributes") + { $phpname = "_printer".$k; - $this->printers_attributes->$phpname = new stdClass(); - for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) { - + $this->printers_attributes->$phpname = new \stdClass(); + for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) + { + $value = $this->serveroutput->response[$i][$j]['value']; $name = str_replace("-","_",$this->serveroutput->response[$i][$j]['name']); - - switch ($name) { + + switch ($name) + { case "printer_uri_supported": $this->available_printers = array_merge($this->available_printers,array($value)); break; case "printer_type": $table = self::_interpretPrinterType($value); - $this->printers_attributes->$phpname->$name = new stdClass(); - - for($l = 0 ; $l < count($table) ; $l++ ) { + $this->printers_attributes->$phpname->$name = new \stdClass(); + + for($l = 0 ; $l < count($table) ; $l++ ) + { $index = '_value'.$l; $this->printers_attributes->$phpname->$name->$index = $table[$l]; } - + break; case '': break; + case 'printer_name': + $this->printer_map[$value] = $k; + break; default: $this->printers_attributes->$phpname->$name = $value; break; - } - - } - $k ++; + } } + $k ++; + } + } } - // }}} - - // {{{ _getEnumVendorExtensions - protected function _getEnumVendorExtensions ($value_parsed) { - switch ($value_parsed) { + + protected function _getEnumVendorExtensions ($value_parsed) + { + switch ($value_parsed) + { case 0x4002: $value = 'Get-Availables-Printers'; break; @@ -541,110 +614,152 @@ class CupsPrintIPP extends ExtendedPrintIPP { break; } - if (isset($value)) - return ($value); - - return sprintf('Unknown: 0x%x',$value_parsed); - } - // }}} + if (isset($value)) + { + return ($value); + } - // {{{ _interpretPrinterType($type) - private function _interpretPrinterType($value) { + return sprintf('Unknown: 0x%x',$value_parsed); + } + + + private function _interpretPrinterType($value) + { $value_parsed = 0; for ($i = strlen($value) ; $i > 0 ; $i --) + { $value_parsed += pow(256,($i - 1)) * ord($value[strlen($value) - $i]); - + } + $type[0] = $type[1] = $type[2] = $type[3] = $type[4] = $type[5] = ''; $type[6] = $type[7] = $type[8] = $type[9] = $type[10] = ''; $type[11] = $type[12] = $type[13] = $type[14] = $type[15] = ''; $type[16] = $type[17] = $type[18] = $type[19] = ''; - - if ($value_parsed %2 == 1) { + + if ($value_parsed %2 == 1) + { $type[0] = 'printer-class'; $value_parsed -= 1; - } - if ($value_parsed %4 == 2 ) { + } + + if ($value_parsed %4 == 2 ) + { $type[1] = 'remote-destination'; $value_parsed -= 2; - } - if ($value_parsed %8 == 4 ) { + } + + if ($value_parsed %8 == 4 ) + { $type[2] = 'print-black'; $value_parsed -= 4; - } - if ($value_parsed %16 == 8 ) { + } + + if ($value_parsed %16 == 8 ) + { $type[3] = 'print-color'; $value_parsed -= 8; - } - if ($value_parsed %32 == 16) { + } + + if ($value_parsed %32 == 16) + { $type[4] = 'hardware-print-on-both-sides'; $value_parsed -= 16; - } - if ($value_parsed %64 == 32) { + } + + if ($value_parsed %64 == 32) + { $type[5] = 'hardware-staple-output'; $value_parsed -= 32; - } - if ($value_parsed %128 == 64) { + } + + if ($value_parsed %128 == 64) + { $type[6] = 'hardware-fast-copies'; $value_parsed -= 64; - } - if ($value_parsed %256 == 128) { + } + + if ($value_parsed %256 == 128) + { $type[7] = 'hardware-fast-copy-collation'; $value_parsed -= 128; - } - if ($value_parsed %512 == 256) { + } + + if ($value_parsed %512 == 256) + { $type[8] = 'punch-output'; $value_parsed -= 256; - } - if ($value_parsed %1024 == 512) { + } + + if ($value_parsed %1024 == 512) + { $type[9] = 'cover-output'; $value_parsed -= 512; - } - if ($value_parsed %2048 == 1024) { + } + + if ($value_parsed %2048 == 1024) + { $type[10] = 'bind-output'; $value_parsed -= 1024; - } - if ($value_parsed %4096 == 2048) { + } + + if ($value_parsed %4096 == 2048) + { $type[11] = 'sort-output'; $value_parsed -= 2048; - } - if ($value_parsed %8192 == 4096) { + } + + if ($value_parsed %8192 == 4096) + { $type[12] = 'handle-media-up-to-US-Legal-A4'; $value_parsed -= 4096; - } - if ($value_parsed %16384 == 8192) { + } + + if ($value_parsed %16384 == 8192) + { $type[13] = 'handle-media-between-US-Legal-A4-and-ISO_C-A2'; $value_parsed -= 8192; - } - if ($value_parsed %32768 == 16384) { + } + + if ($value_parsed %32768 == 16384) + { $type[14] = 'handle-media-larger-than-ISO_C-A2'; $value_parsed -= 16384; - } - if ($value_parsed %65536 == 32768) { + } + + if ($value_parsed %65536 == 32768) + { $type[15] = 'handle-user-defined-media-sizes'; $value_parsed -= 32768; - } - if ($value_parsed %131072 == 65536) { + } + + if ($value_parsed %131072 == 65536) + { $type[16] = 'implicit-server-generated-class'; $value_parsed -= 65536; - } - if ($value_parsed %262144 == 131072) { + } + + if ($value_parsed %262144 == 131072) + { $type[17] = 'network-default-printer'; $value_parsed -= 131072; - } - if ($value_parsed %524288 == 262144) { + } + + if ($value_parsed %524288 == 262144) + { $type[18] = 'fax-device'; $value_parsed -= 262144; - } - return $type; - } - // }}} + } - // {{{ _interpretEnum() - protected function _interpretEnum($attribute_name,$value) { - + return $type; + } + + + protected function _interpretEnum($attribute_name,$value) + { $value_parsed = self::_interpretInteger($value); - - switch ($attribute_name) { + + switch ($attribute_name) + { case 'cpi': case 'lpi': $value = $value_parsed; @@ -652,20 +767,8 @@ class CupsPrintIPP extends ExtendedPrintIPP { default: $value = parent::_interpretEnum($attribute_name,$value); break; - } - - - return $value; - } - // }}} - -}; + } -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ -?> + return $value; + } +} \ No newline at end of file diff --git a/htdocs/includes/printipp/ExtendedPrintIPP.php b/htdocs/includes/printipp/ExtendedPrintIPP.php index e736f4bd972..3effacb828f 100644 --- a/htdocs/includes/printipp/ExtendedPrintIPP.php +++ b/htdocs/includes/printipp/ExtendedPrintIPP.php @@ -1,5 +1,5 @@ document_uri = $uri; $this->setup->uri = 1; } - + if(!$this->_stringUri()) + { return FALSE; - + } + $this->output = $this->stringjob; - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { - - if(self::_parseServerOutput()) { + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + if(self::_parseServerOutput()) + { $this->_parseJobAttributes(); $this->_getJobId(); //$this->_getPrinterUri(); $this->_getJobUri(); } } - + $this->attributes = &$this->job_attributes; - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf("printing uri %s, job %s: ",$uri,$this->last_job) .$this->serveroutput->status,3); - else { + } + else + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_errorLog(sprintf("printing uri %s: ",$uri,$this->last_job) .$this->serveroutput->status,1); - } - return $this->serveroutput->status; } - + return $this->serveroutput->status; + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("printing uri $uri : OPERATION FAILED",1); - - return false; - } - // }}} - // {{{ purgeJobs() - public function purgeJobs() { - + return false; + } + + + public function purgeJobs() + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("purgeJobs: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("purgeJobs: Printer URI is not set: die\n")); self::_errorLog("purgeJobs: Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x12) // purge-Jobs | operation-id . $this->meta->operation_id // request-id @@ -164,116 +169,141 @@ class ExtendedPrintIPP extends PrintIPP { . self::_giveMeStringLength(chr(0x01)) . chr(0x01) . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("purging jobs of %s\n"),$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['admin'])) { + + if (self::_sendHttp ($post_values,$this->paths['admin'])) + { self::_parseServerOutput(); self::_parseAttributes(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("purging jobs of %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("purging jobs of %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("purging jobs of %s : OPERATION FAILED"), $this->printer_uri),3); - - return false; + + return false; } - // }}} - - // {{{ createJob() - public function createJob() { - - + public function createJob() + { self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("createJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("createJob: Printer URI is not set: die\n")); self::_errorLog("createJob: Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->setup->copies)) + { self::setCopies(1); + } if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + if (!isset($this->setup->jobname)) + { if (is_readable($this->data)) + { self::setJobName(basename($this->data),true); + } else + { self::setJobName(); + } + } unset($this->setup->jobname); if (!isset($this->timeout)) + { $this->timeout = 60; - + } + $timeout = self::_integerBuild($this->timeout); - $this->meta->timeout = chr(0x21) // integer . self::_giveMeStringLength("multiple-operation-time-out") . "multiple-operation-time-out" . self::_giveMeStringLength($timeout) . $timeout; - + $jobattributes = ''; $operationattributes = ''; $printerattributes = ''; self::_buildValues($operationattributes,$jobattributes,$printerattributes); - + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x05) // Create-Job | operation-id . $this->meta->operation_id // request-id @@ -292,40 +322,44 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->page_ranges . $jobattributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + unset ($this->meta->copies,$this->meta->sides,$this->meta->page_ranges); self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("creating job %s, printer %s\n"),$this->last_job,$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['printers'])) - if(self::_parseServerOutput()) { + { + if(self::_parseServerOutput()) + { $this->_getJobId(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + else + { $this->jobs = array_merge($this->jobs,array('')); $this->jobs_uri = array_merge($this->jobs_uri,array('')); - } + } + } - - - - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("Create job: job %s"),$this->last_job) .$this->serveroutput->status,3); - else { + } + else + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); @@ -333,186 +367,207 @@ class ExtendedPrintIPP extends PrintIPP { } return $this->serveroutput->status; } - + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("Creating job on %s : OPERATION FAILED"), $this->printer_uri),3); - + $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - return false; + return false; } - // }}} - - // {{{ sendDocument($job) - public function sendDocument($job,$is_last=false){ - + public function sendDocument($job,$is_last=false) + { self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); if (!$this->_stringDocument($job,$is_last)) + { return FALSE; - - if (is_readable($this->data)){ + } + + if (is_readable($this->data)) + { self::_putDebug( _("sending Document\n")); - + $this->output = $this->stringjob; - + if ($this->setup->datatype == "TEXT") - $this->output .= chr(0x16); // ASCII "SYN" - - + { + $this->output .= chr(0x16); + } // ASCII "SYN" + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output, "File" => $this->data); - + if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed)) + { $post_values = array_merge($post_values,array("Filetype"=>"TEXT")); - - } else { + } + } + else + { self::_putDebug( _("sending DATA as document\n")); - + $this->output = $this->stringjob; $this->output .= $this->datahead; $this->output .= $this->data; $this->output .= $this->datatail; - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - - } - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { - - if(self::_parseServerOutput()) { + } + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + + if(self::_parseServerOutput()) + { $this->_getJobId(); //$this->_getPrinterUri(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + else + { $this->jobs = array_merge($this->jobs,array($job)); $this->jobs_uri = array_merge($this->jobs_uri,array($job)); } - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf("sending document, job %s: %s",$job,$this->serveroutput->status),3); - else { + } + else + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_errorLog(sprintf("sending document, job %s: %s",$job,$this->serveroutput->status),1); - } - return $this->serveroutput->status; - } + return $this->serveroutput->status; + } $this->status = array_merge($this->status,array("OPERATION FAILED")); $this->jobs = array_merge($this->jobs,array($job)); $this->jobs_uri = array_merge($this->jobs_uri,array($job)); self::_errorLog(sprintf("sending document, job %s : OPERATION FAILED",$job),1); - - return false; + + return false; } - // }}} - // {{{ sendURI ($uri,$job,$is_last=false) - public function sendURI ($uri,$job,$is_last=false){ + public function sendURI ($uri,$job,$is_last=false) + { self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); if (!$this->_stringSendUri($uri,$job,$is_last)) + { return FALSE; - + } + self::_putDebug( _("sending URI $uri\n")); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { - - if(self::_parseServerOutput()) { + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + if(self::_parseServerOutput()) + { $this->_getJobId(); //$this->_getPrinterUri(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + else + { $this->jobs = array_merge($this->jobs,array($job)); $this->jobs_uri = array_merge($this->jobs_uri,array($job)); } - } - + $this->attributes = &$this->job_attributes; - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf("sending uri %s, job %s: %s",$uri,$job,$this->serveroutput->status),3); - else { + } + else + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_errorLog(sprintf("sending uri, job %s: %s",$uri,$job,$this->serveroutput->status),1); - } - return $this->serveroutput->status; - } + return $this->serveroutput->status; + } $this->status = array_merge($this->status,array("OPERATION FAILED")); $this->jobs = array_merge($this->jobs,array($job)); $this->jobs_uri = array_merge($this->jobs_uri,array($job)); self::_errorLog(sprintf("sending uri %s, job %s : OPERATION FAILED",$uri,$job),1); - - return false; - } - // }}} - // {{{ pausePrinter () - public function pausePrinter() { - + return false; + } + + + public function pausePrinter() + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("pausePrinter: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("pausePrinter: Printer URI is not set: die\n")); self::_errorLog("pausePrinter: Printer URI is not set, die",2); return FALSE; - } } - + } + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x10) // Pause-Printer | operation-id . $this->meta->operation_id // request-id @@ -527,81 +582,94 @@ class ExtendedPrintIPP extends PrintIPP { . self::_giveMeStringLength(chr(0x01)) . chr(0x01) */ . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("pause printer %s\n"),$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['admin'])) { + + if (self::_sendHttp ($post_values,$this->paths['admin'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } + } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("Pause printer %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("pause printer %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("pause printer %s : OPERATION FAILED"), $this->printer_uri),3); - - return false; - } - // }}} - // {{{ resumePrinter () - public function resumePrinter() { - + return false; + } + + + public function resumePrinter() + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("resumePrinter: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("resumePrinter: Printer URI is not set: die\n")); self::_errorLog(" Printer URI is not set, die",2); return FALSE; - } } - + } + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x11) // suse-Printer | operation-id . $this->meta->operation_id // request-id @@ -611,82 +679,97 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->printer_uri . $this->meta->username . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("resume printer %s\n"),$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['admin'])) { + + if (self::_sendHttp ($post_values,$this->paths['admin'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } + } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("resume printer %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("resume printer %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("resume printer %s : OPERATION FAILED"), $this->printer_uri),3); - - return false; - } - // }}} - // {{{ holdJob ($job_uri) - public function holdJob ($job_uri,$until='indefinite') { - + return false; + } + + + public function holdJob ($job_uri,$until='indefinite') + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri))); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->meta->message)) + { $this->meta->message = ''; + } self::_setJobUri($job_uri); $until_strings = array('no-hold','day-time','evening','night','weekend','second-shift','third-shift'); if (in_array($until,$until_strings)) + { true; + } else + { $until = 'indefinite'; + } $this->meta->job_hold_until = chr(0x42) // keyword . self::_giveMeStringLength('job-hold-until') . 'job-hold-until' . self::_giveMeStringLength($until) . $until; - + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0C) // Hold-Job | operation-id . $this->meta->operation_id // request-id @@ -698,68 +781,81 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->message . $this->meta->job_hold_until . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("hold job %s until %s\n"),$job_uri,$until)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['jobs'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("hold job %s until %s: "),$job_uri,$until) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("hold job %s until %s: "),$job_uri,$until) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("hold job %s until %s : OPERATION FAILED"), $job_uri,$until),3); - - return false; + + return false; } - // }}} - - // {{{ releaseJob ($job_uri) - public function releaseJob ($job_uri) { + + public function releaseJob ($job_uri) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri))); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->meta->message)) + { $this->meta->message = ''; + } self::_setJobUri($job_uri); - + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0D) // Hold-Job | operation-id . $this->meta->operation_id // request-id @@ -770,75 +866,85 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->username . $this->meta->message . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("release job %s\n"),$job_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['jobs'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("release job %s: "),$job_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("release job %s: "),$job_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("release job %s: OPERATION FAILED"), $job_uri),3); - - return false; + + return false; } - // }}} - - // {{{ restartJob ($job_uri) - public function restartJob ($job_uri) { - + + + public function restartJob ($job_uri) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri))); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->meta->message)) + { $this->meta->message = ''; + } self::_setJobUri($job_uri); - - + $jobattributes = ''; $operationattributes = ''; $printerattributes = ''; self::_buildValues ($operationattributes,$jobattributes,$printerattributes); - $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0E) // Hold-Job | operation-id . $this->meta->operation_id // request-id @@ -850,92 +956,110 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->message . $jobattributes // job-hold-until is set by setAttribute($attribute,$value) . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("release job %s\n"),$job_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['jobs'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("release job %s: "),$job_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("release job %s: "),$job_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("release job %s: OPERATION FAILED"), $job_uri),3); - - return false; + + return false; } - // }}} - - // {{{ setJobAttributes ($job_uri,$deleted_attributes=array()) - public function setJobAttributes ($job_uri,$deleted_attributes=array()) { - + + + public function setJobAttributes ($job_uri,$deleted_attributes=array()) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri))); self::_setOperationId(); $this->parsed = array(); unset ($this->attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - - if (!isset($this->meta->message)) - $this->meta->message = ''; + } + + if (!isset($this->meta->message)) + { + $this->meta->message = ''; + } - if (!isset($this->meta->copies)) + { $this->meta->copies = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; + } self::_setJobUri($job_uri); - + $operationattributes = ''; $jobattributes = ''; $printerattributes = ''; self::_buildValues ($operationattributes,$jobattributes,$printerattributes); - + $this->meta->deleted_attributes = ""; for ($i = 0 ; $i < count($deleted_attributes) ; $i++) - $this->meta->deleted_attributes .= chr(0x16) // out-of-band value - . self::_giveMeStringLength($deleted_attributes[$i]) - . $deleted_attributes[$i] - . chr(0x0).chr(0x0); // value-length = 0; - - + { + $this->meta->deleted_attributes .= chr(0x16) // out-of-band value + . self::_giveMeStringLength($deleted_attributes[$i]) + . $deleted_attributes[$i] + . chr(0x0).chr(0x0); + } // value-length = 0; + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x14) // Set-Job-Attributes | operation-id . $this->meta->operation_id // request-id @@ -952,47 +1076,52 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->page_ranges . $this->meta->deleted_attributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("set job attributes for job %s\n"),$job_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['jobs'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("set job attributes for job %s: "),$job_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("set job attributes for job %s: "),$job_uri) .$this->serveroutput->status,1); + } $this->last_job = $job_uri; $this->jobs_uri[count($this->jobs_uri) - 1] = $job_uri; return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("set job attributes for job %s: OPERATION FAILED"), $job_uri),3); - - return false; + + return false; } - // }}} - - // {{{ setPrinterAttributes () - public function setPrinterAttributes ($document_format='',$deleted_attributes=array()) { + + + public function setPrinterAttributes ($document_format='',$deleted_attributes=array()) + { /* $document_format (RFC 3380) If the client includes this attribute, the Printer MUST change the supplied attributes for the document format specified by @@ -1010,55 +1139,72 @@ class ExtendedPrintIPP extends PrintIPP { supplied attributes for all document formats, whether or not they vary by document-format. */ - + $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); unset ($this->attributes); - + self::_setOperationId(); $this->parsed = array(); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->meta->message)) + { $this->meta->message = ''; - + } + if (!isset($this->meta->copies)) + { $this->meta->copies = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + if ($document_format) + { $document_format = chr(0x49) // document-format tag - . self::_giveMeStringLength('document-format') - . 'document-format' // - . self::_giveMeStringLength($document_format) - . $document_format; // value + . self::_giveMeStringLength('document-format') + . 'document-format' // + . self::_giveMeStringLength($document_format) + . $document_format; + } // value $operationattributes = ''; $jobattributes = ''; $printerattributes = ''; self::_buildValues ($operationattributes,$jobattributes,$printerattributes); - + $this->meta->deleted_attributes = ""; for ($i = 0 ; $i < count($deleted_attributes) ; $i++) + { $this->meta->deleted_attributes .= chr(0x16) // out-of-band "deleted" value . self::_giveMeStringLength($deleted_attributes[$i]) . $deleted_attributes[$i] - . chr(0x0).chr(0x0); // value-length = 0; - - + . chr(0x0).chr(0x0); + } // value-length = 0; + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x13) // Set-Printer-Attributes | operation-id . $this->meta->operation_id // request-id @@ -1076,144 +1222,176 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->page_ranges . $this->meta->deleted_attributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("set printer attributes for job %s\n"),$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("set printer attributes for printer %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("set printer attributes for printer %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("set printer attributes for printer %s: OPERATION FAILED"), $this->printer_uri),1); - - return false; - + + return false; } - // }}} -// REQUEST BUILDING - - // {{{ _setDocumentUri ($job_uri) - protected function _setDocumentUri () { - + // REQUEST BUILDING + protected function _setDocumentUri () + { $this->meta->document_uri = chr(0x45) // type uri . chr(0x00).chr(0x0c) // name-length . "document-uri" . self::_giveMeStringLength($this->document_uri) . $this->document_uri; - + self::_putDebug( "document uri is: ".$this->document_uri."\n"); $this->setup->document_uri = 1; - } - // }}} - // {{{ _stringUri () - protected function _stringUri () { - + + protected function _stringUri () + { self::_setDocumentUri(); - - if (!isset($this->setup->document_uri)) { + + if (!isset($this->setup->document_uri)) + { trigger_error(_("_stringUri: Document URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringUri: Document URI is not set: die\n")); self::_errorLog("Document URI is not set, die",2); return FALSE; } unset ($this->setup->document_uri); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringUri: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringUri: Printer URI is not set: die\n")); self::_errorLog("_stringUri: Printer URI is not set, die",2); return FALSE; - } } + } if (!isset($this->setup->charset)) + { $this->meta->charset = ""; - // self::setCharset('us-ascii'); + } if (!isset($this->setup->datatype)) + { self::setBinary(); - if (!isset($this->setup->uri)) { + } + if (!isset($this->setup->uri)) + { trigger_error(_("_stringUri: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringUri: Printer URI is not set: die\n")); self::_errorLog("Printer URI is not set, die",2); return FALSE; - } + } if (!isset($this->setup->copies)) + { self::setCopies(1); - + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->setup->mime_media_type)) + { self::setMimeMediaType(); + } unset ($this->setup->mime_media_type); - + if (!isset($this->setup->jobname)) + { if (is_readable($this->data)) + { self::setJobName(basename($this->data),true); + } else + { self::setJobName(); + } + } unset($this->setup->jobname); if (!isset($this->meta->username)) + { self::setUserName(); + } if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; - + } + if (!isset($this->meta->document_name)) + { $this->meta->document_name = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + $jobattributes = ''; $operationattributes = ''; $printerattributes = ''; self::_buildValues($operationattributes,$jobattributes,$printerattributes); - + self::_setOperationId(); - + if (!isset($this->error_generation->request_body_malformed)) + { $this->error_generation->request_body_malformed = ""; - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x03) // Print-URI | operation-id . $this->meta->operation_id // request-id @@ -1234,72 +1412,98 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->page_ranges . $jobattributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); return TRUE; } - // }}} - - // {{{ _stringDocument ($job,$is_last) - protected function _stringDocument ($job,$is_last) { - - if ($is_last == false) - $is_last = chr(0x00); - else - $is_last = chr(0x01); - - if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - if (!isset($this->setup->datatype)) - self::setBinary(); - if (!isset($this->setup->uri)) { + + protected function _stringDocument ($job,$is_last) + { + if ($is_last == false) + { + $is_last = chr(0x00); + } + else + { + $is_last = chr(0x01); + } + + if (!isset($this->setup->charset)) + { + self::setCharset(); + } + if (!isset($this->setup->datatype)) + { + self::setBinary(); + } + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n")); self::_errorLog(" Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->copies)) + { $this->meta->copies = ""; - + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->setup->mime_media_type)) + { $this->meta->mime_media_type = ""; + } if ($this->setup->datatype != "TEXT") + { unset ($this->setup->mime_media_type); - + } + if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; - + } + if (!isset($this->meta->document_name)) + { $this->meta->document_name = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + $operationattributes = ''; $jobattributes = ''; $printerattributes = ''; self::_buildValues($operationattributes,$jobattributes,$printerattributes); - + self::_setOperationId(); - $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x06) // Send-Document | operation-id . $this->meta->operation_id // request-id @@ -1322,84 +1526,107 @@ class ExtendedPrintIPP extends PrintIPP { . self::_giveMeStringLength($is_last) . $is_last . chr(0x03); // end-of-attributes | end-of-attributes-tag - self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); return TRUE; } - // }}} - // {{{ _stringSendUri ($uri,$job,$is_last) - protected function _stringSendUri ($uri,$job,$is_last) { - + + protected function _stringSendUri ($uri,$job,$is_last) + { $this->document_uri = $uri; self::_setDocumentUri(); - - if (!isset($this->setup->document_uri)) { + + if (!isset($this->setup->document_uri)) + { trigger_error(_("_stringUri: Document URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringUri: Document URI is not set: die\n")); self::_errorLog("Document URI is not set, die",2); return FALSE; } unset ($this->setup->document_uri); - - - if ($is_last == false) - $is_last = chr(0x00); - else - $is_last = chr(0x01); - - if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - if (!isset($this->setup->datatype)) - self::setBinary(); - if (!isset($this->setup->uri)) { + if ($is_last == false) + { + $is_last = chr(0x00); + } + else + { + $is_last = chr(0x01); + } + + if (!isset($this->setup->charset)) + { + self::setCharset(); + } + if (!isset($this->setup->datatype)) + { + self::setBinary(); + } + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n")); self::_errorLog(" Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->copies)) + { $this->meta->copies = ""; - + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->setup->mime_media_type)) + { $this->meta->mime_media_type = ""; + } unset ($this->setup->mime_media_type); - + if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; - + } + if (!isset($this->meta->document_name)) + { $this->meta->document_name = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + $operationattributes = ''; $jobattributes = ''; $printerattributes = ''; self::_buildValues($operationattributes,$jobattributes,$printerattributes); - + self::_setOperationId(); - $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x07) // Send-Uri | operation-id . $this->meta->operation_id // request-id @@ -1422,20 +1649,8 @@ class ExtendedPrintIPP extends PrintIPP { . self::_giveMeStringLength($is_last) . $is_last . chr(0x03); // end-of-attributes | end-of-attributes-tag - self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); return TRUE; } - // }}} - -}; - -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ -?> +} \ No newline at end of file diff --git a/htdocs/includes/printipp/PrintIPP.php b/htdocs/includes/printipp/PrintIPP.php index 9ed502c2d11..ffda9e8f1f7 100644 --- a/htdocs/includes/printipp/PrintIPP.php +++ b/htdocs/includes/printipp/PrintIPP.php @@ -1,5 +1,5 @@ _stringJob()) + { return FALSE; - - if (is_readable($this->data)){ + } + + if (is_readable($this->data)) + { self::_putDebug( _("Printing a FILE\n"),3); - + $this->output = $this->stringjob; - + if ($this->setup->datatype == "TEXT") + { $this->output .= chr(0x16); - - + } + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output, "File" => $this->data); - + if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed)) + { $post_values = array_merge($post_values,array("Filetype"=>"TEXT")); - - } else { + } + } + else + { self::_putDebug( _("Printing DATA\n"),3); - + $this->output = $this->stringjob; $this->output .= $this->datahead; $this->output .= $this->data; @@ -99,25 +90,25 @@ class PrintIPP extends BasicIPP { $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - - } - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { - - if(self::_parseServerOutput()) { + } + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + if(self::_parseServerOutput()) + { $this->_getJobId(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + else + { $this->jobs = array_merge($this->jobs,array('')); $this->jobs_uri = array_merge($this->jobs_uri,array('')); } - } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") @@ -131,138 +122,174 @@ class PrintIPP extends BasicIPP { self::_errorLog(sprintf("printing job: ",$this->last_job) .$this->serveroutput->status,1); if ($this->with_exceptions) { - throw new ippException(sprintf("job status: %s", + throw new ippException(sprintf("job status: %s", $this->serveroutput->status)); } } return $this->serveroutput->status; - - } + } $this->status = array_merge($this->status,array("OPERATION FAILED")); $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_errorLog("printing job : OPERATION FAILED",1); - - return false; - } - // }}} - // {{{ cancelJob ($job_uri) - public function cancelJob ($job_uri) { - + return false; + } + + public function cancelJob ($job_uri) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - + self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); - + if (!$this->_stringCancel($job_uri)) - return FALSE; - + { + return FALSE; + } + self::_putDebug( _("Cancelling Job $job_uri\n"),3); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); - - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,3); - else - self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,1); - return $this->serveroutput->status; - } + else + { + self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,1); + } + return $this->serveroutput->status; + } - $this->status = array_merge($this->status,array("OPERATION FAILED")); - self::_errorLog("cancelling job : OPERATION FAILED",3); - - return false; + $this->status = array_merge($this->status,array("OPERATION FAILED")); + self::_errorLog("cancelling job : OPERATION FAILED",3); + + return false; } - // }}} - // {{{ validateJob () - public function validateJob () { - + public function validateJob () + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - + $this->serveroutput->response = ''; self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); - - - self::_putDebug( _("Validate Job\n"),2); - - if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - if (!isset($this->setup->datatype)) - self::setBinary(); - if (!isset($this->setup->uri)) { + self::_putDebug( _("Validate Job\n"),2); + + if (!isset($this->setup->charset)) + { + self::setCharset(); + } + if (!isset($this->setup->datatype)) + { + self::setBinary(); + } + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3); self::_errorLog(" Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->meta->copies)) + { self::setCopies(1); + } + if (!isset($this->setup->copies)) + { self::setCopies(1); - + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->setup->mime_media_type)) + { self::setMimeMediaType(); + } + if ($this->setup->datatype != "TEXT") - unset ($this->setup->mime_media_type); - + { + unset ($this->setup->mime_media_type); + } + if (!isset($this->setup->jobname)) + { if (is_readable($this->data)) + { self::setJobName(basename($this->data),true); + } else + { self::setJobName(); + } + } unset($this->setup->jobname); if (!isset($this->meta->username)) + { self::setUserName(); + } if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; - + } + if (!isset($this->meta->document_name)) + { $this->meta->document_name = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + $jobattributes = ''; $operationattributes = ''; $printerattributes = ''; self::_buildValues ($operationattributes,$jobattributes,$printerattributes); - + self::_setOperationId(); $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number @@ -284,43 +311,45 @@ class PrintIPP extends BasicIPP { . $this->meta->page_ranges . $jobattributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['printers'])) - if(self::_parseServerOutput()) - self::_parseAttributes(); - - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + { + if(self::_parseServerOutput()) + { + self::_parseAttributes(); + } + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("validate job: ".$this->serveroutput->status,3); - else - self::_errorLog("validate job: ".$this->serveroutput->status,1); - - return $this->serveroutput->status; - } + else + { + self::_errorLog("validate job: ".$this->serveroutput->status,1); + } + return $this->serveroutput->status; + } - $this->status = array_merge($this->status,array("OPERATION FAILED")); - self::_errorLog("validate job : OPERATION FAILED",3); - - return false; + $this->status = array_merge($this->status,array("OPERATION FAILED")); + self::_errorLog("validate job : OPERATION FAILED",3); + + return false; } - // }}} - // {{{ getPrinterAttributes() - public function getPrinterAttributes() { - + public function getPrinterAttributes() + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); @@ -330,32 +359,42 @@ class PrintIPP extends BasicIPP { self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3); self::_errorLog(" Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0b) // Print-URI | operation-id . $this->meta->operation_id // request-id @@ -366,109 +405,137 @@ class PrintIPP extends BasicIPP { . $this->meta->username . $printerattributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("Getting printer attributes of %s\n"),$this->printer_uri),2); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['root'])) + { if (self::_parseServerOutput()) + { self::_parsePrinterAttributes(); - + } + } + $this->attributes = &$this->printer_attributes; - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("getting printer attributes of %s: %s"),$this->printer_uri, $this->serveroutput->status),3); + } else + { self::_errorLog(sprintf(_("getting printer attributes of %s: %s"),$this->printer_uri, $this->serveroutput->status),1); - - return $this->serveroutput->status; } - $this->status = array_merge($this->status,array("OPERATION FAILED")); - self::_errorLog(date("Y-m-d H:i:s : ") - .basename($_SERVER['PHP_SELF']) - .sprintf(_("getting printer's attributes of %s : OPERATION FAILED"), - $this->printer_uri),3); - - return false; - } - // }}} + return $this->serveroutput->status; + } - // {{{ getJobs ($my_jobs=true,$limit=0,$which_jobs=""); - public function getJobs($my_jobs=true,$limit=0,$which_jobs="not-completed",$subset=false) { - + $this->status = array_merge($this->status,array("OPERATION FAILED")); + self::_errorLog(date("Y-m-d H:i:s : ") + .basename($_SERVER['PHP_SELF']) + .sprintf(_("getting printer's attributes of %s : OPERATION FAILED"), + $this->printer_uri),3); + + return false; + } + + public function getJobs($my_jobs=true,$limit=0,$which_jobs="not-completed",$subset=false) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("getJobs: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3); self::_errorLog("getJobs: Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); + } - if ($limit) { + if ($limit) + { $limit = self::_integerBuild($limit); $this->meta->limit = chr(0x21) // integer . self::_giveMeStringLength('limit') . 'limit' . self::_giveMeStringLength($limit) . $limit; - } else + } + else + { $this->meta->limit = ''; - + } + if ($which_jobs == 'completed') + { $this->meta->which_jobs = chr(0x44) // keyword . self::_giveMeStringLength('which-jobs') . 'which-jobs' . self::_giveMeStringLength($which_jobs) . $which_jobs; + } else + { $this->meta->which_jobs = ""; + } if ($my_jobs) + { $this->meta->my_jobs = chr(0x22) // boolean . self::_giveMeStringLength('my-jobs') . 'my-jobs' . self::_giveMeStringLength(chr(0x01)) . chr(0x01); + } else + { $this->meta->my_jobs = ''; - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0A) // Get-Jobs | operation-id . $this->meta->operation_id // request-id @@ -479,9 +546,9 @@ class PrintIPP extends BasicIPP { . $this->meta->username . $this->meta->limit . $this->meta->which_jobs - . $this->meta->my_jobs - ; - if ($subset) { + . $this->meta->my_jobs; + if ($subset) + { $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') @@ -502,106 +569,122 @@ class PrintIPP extends BasicIPP { . self::_giveMeStringLength('') . '' . self::_giveMeStringLength('job-state-reason') - . 'job-state-reason' - ; + . 'job-state-reason'; } - else { # cups 1.4.4 doesn't return much of anything without this + else + { # cups 1.4.4 doesn't return much of anything without this $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' . self::_giveMeStringLength('all') - . 'all' - ; + . 'all'; } $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { if (self::_parseServerOutput()) + { self::_parseJobsAttributes(); - + } + } + $this->attributes = &$this->jobs_attributes; - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("getting jobs of printer %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("getting jobs of printer %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("getting jobs of %s : OPERATION FAILED"), $this->printer_uri),3); - + return false; } - // }}} - // {{{ getJobAttributes ($job_uri,subset="false",$attributes_group="all"); - public function getJobAttributes($job_uri,$subset=false,$attributes_group="all") { - + + public function getJobAttributes($job_uri,$subset=false,$attributes_group="all") + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - - if (!$job_uri) { + + if (!$job_uri) + { trigger_error(_("getJobAttributes: Job URI is not set, die.")); return FALSE; } - + self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("getJobs: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3); self::_errorLog("getJobs: Printer URI is not set, die",2); return FALSE; - } } - + } + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); + } $this->meta->job_uri = chr(0x45) // URI . self::_giveMeStringLength('job-uri') . 'job-uri' . self::_giveMeStringLength($job_uri) . $job_uri; - + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x09) // Get-Job-Attributes | operation-id . $this->meta->operation_id // request-id @@ -609,10 +692,10 @@ class PrintIPP extends BasicIPP { . $this->meta->charset . $this->meta->language . $this->meta->job_uri - . $this->meta->username - ; - if ($subset) - $this->stringjob .= + . $this->meta->username; + if ($subset) + { + $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' @@ -632,10 +715,12 @@ class PrintIPP extends BasicIPP { . self::_giveMeStringLength('') . '' . self::_giveMeStringLength('job-state-reason') - . 'job-state-reason' - ; - elseif($attributes_group) { - switch($attributes_group) { + . 'job-state-reason'; + } + elseif($attributes_group) + { + switch($attributes_group) + { case 'job-template': break; case 'job-description': @@ -646,127 +731,116 @@ class PrintIPP extends BasicIPP { trigger_error(_('not a valid attribute group: ').$attributes_group,E_USER_NOTICE); $attributes_group = ''; break; - } + } $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' . self::_giveMeStringLength($attributes_group) . $attributes_group; - } + } $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { if (self::_parseServerOutput()) + { self::_parseJobAttributes(); - + } + } + $this->attributes = &$this->job_attributes; - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("getting job attributes for %s: "),$job_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("getting job attributes for %s: "),$job_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("getting jobs attributes of %s : OPERATION FAILED"), $job_uri),3); - - return false; + + return false; } - // }}} - - // {{{ getPrinters(); - public function getPrinters() { - + public function getPrinters() + { // placeholder for vendor extension operation (getAvailablePrinters for CUPS) $this->jobs = array_merge($this->jobs,array('')); $this->jobs_uri = array_merge($this->jobs_uri,array('')); $this->status = array_merge($this->status,array('')); } - // }}} -/****************** -* -* DEVELOPPEMENT FUNCTIONS -* -*******************/ - - // {{{ generateError($error) - public function generateError ($error) { - switch ($error) { + public function generateError ($error) + { + switch ($error) + { case "request_body_malformed": $this->error_generation->request_body_malformed = chr(0xFF); break; default: true; break; - } - // }}} + } - // {{{ resetError ($error) trigger_error(sprintf(_('Setting Error %s'),$error),E_USER_NOTICE); } - public function resetError ($error) { + public function resetError ($error) + { unset ($this->error_generation->$error); trigger_error(sprintf(_('Reset Error %s'),$error),E_USER_NOTICE); } - // }}} -/****************** -* -* PROTECTED FUNCTIONS -* -*******************/ - -// SETUP - - // {{{ _setOperationId () - protected function _setOperationId () { + // SETUP + protected function _setOperationId () + { $prepend = ''; $this->operation_id += 1; $this->meta->operation_id = self::_integerBuild($this->operation_id); self::_putDebug( "operation id is: ".$this->operation_id."\n",2); } - // }}} - // {{{ _setJobId() - protected function _setJobId() { + protected function _setJobId() + { $this->meta->jobid +=1; $prepend = ''; $prepend_length = 4 - strlen($this->meta->jobid); for ($i = 0; $i < $prepend_length ; $i++ ) + { $prepend .= '0'; + } return $prepend.$this->meta->jobid; } - // }}} - // {{{ _setJobUri ($job_uri) - protected function _setJobUri ($job_uri) { - + protected function _setJobUri ($job_uri) + { $this->meta->job_uri = chr(0x45) // type uri . chr(0x00).chr(0x07) // name-length . "job-uri" @@ -776,441 +850,490 @@ class PrintIPP extends BasicIPP { self::_putDebug( "job-uri is: ".$job_uri."\n",2); } - // }}} - -// RESPONSE PARSING - - // {{{ _parsePrinterAttributes() - protected function _parsePrinterAttributes() { + // RESPONSE PARSING + protected function _parsePrinterAttributes() + { //if (!preg_match('#successful#',$this->serveroutput->status)) // return false; $k = -1; + $l = 0; for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) + { for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++) - if (!empty($this->serveroutput->response[$i][$j]['name'])) { + { + if (!empty($this->serveroutput->response[$i][$j]['name'])) + { $k++; $l = 0; $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes']; $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name']; $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type']; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } else { + } + else + { $l ++; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; } + } + } $this->serveroutput->response = array(); - - $this->printer_attributes = new stdClass(); - for ($i = 0 ; $i < count($this->parsed) ; $i ++) { + + $this->printer_attributes = new \stdClass(); + for ($i = 0 ; $i < count($this->parsed) ; $i ++) + { $name = $this->parsed[$i]['name']; $php_name = str_replace('-','_',$name); $type = $this->parsed[$i]['type']; $range = $this->parsed[$i]['range']; - $this->printer_attributes->$php_name = new stdClass(); + $this->printer_attributes->$php_name = new \stdClass(); $this->printer_attributes->$php_name->_type = $type; $this->printer_attributes->$php_name->_range = $range; - for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) { + for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) + { $value = $this->parsed[$i][$j]; $index = '_value'.$j; $this->printer_attributes->$php_name->$index = $value; } } - + $this->parsed = array(); - - } - // }}} - - // {{{ _parseJobsAttributes() - protected function _parseJobsAttributes() { + protected function _parseJobsAttributes() + { //if ($this->serveroutput->status != "successfull-ok") // return false; - + $job = -1; - for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) { + $l = 0; + for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) + { if ($this->serveroutput->response[$i]['attributes'] == "job-attributes") + { $job ++; + } $k = -1; for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++) - if (!empty($this->serveroutput->response[$i][$j]['name'])) { + { + if (!empty($this->serveroutput->response[$i][$j]['name'])) + { $k++; $l = 0; $this->parsed[$job][$k]['range'] = $this->serveroutput->response[$i]['attributes']; $this->parsed[$job][$k]['name'] = $this->serveroutput->response[$i][$j]['name']; $this->parsed[$job][$k]['type'] = $this->serveroutput->response[$i][$j]['type']; $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } else { + } + else + { $l ++; $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } - } - - $this->serveroutput->response = array(); - $this->jobs_attributes = new stdClass(); - for ($job_nbr = 0 ; $job_nbr <= $job ; $job_nbr ++) { - $job_index = "job_".$job_nbr; - $this->jobs_attributes->$job_index = new stdClass(); - for ($i = 0 ; $i < count($this->parsed[$job_nbr]) ; $i ++) { - $name = $this->parsed[$job_nbr][$i]['name']; - $php_name = str_replace('-','_',$name); - $type = $this->parsed[$job_nbr][$i]['type']; - $range = $this->parsed[$job_nbr][$i]['range']; - $this->jobs_attributes->$job_index->$php_name = new stdClass(); - $this->jobs_attributes->$job_index->$php_name->_type = $type; - $this->jobs_attributes->$job_index->$php_name->_range = $range; - for ($j = 0 ; $j < (count($this->parsed[$job_nbr][$i]) - 3) ; $j ++) { - # This causes incorrect parsing of integer job attributes. - # 2010-08-16 - # bpkroth - #$value = self::_interpretAttribute($name,$type,$this->parsed[$job_nbr][$i][$j]); - $value = $this->parsed[$job_nbr][$i][$j]; - $index = '_value'.$j; - $this->jobs_attributes->$job_index->$php_name->$index = $value; - } - } - } - - $this->parsed = array(); - - - } - // }}} - - // {{{ _readAttribute($attributes_type,$ji,&$collection=false) - protected function _readAttribute($attributes_type) { - - $tag = ord($this->serveroutput->body[$this->_parsing->offset]); - - $this->_parsing->offset += 1; - $j = $this->index; - - $tag = self::_readTag($tag); - - switch ($tag) { - case "begCollection": //RFC3382 (BLIND CODE) - if ($this->end_collection) - $this->index --; - $this->end_collection = false; - $this->serveroutput->response[$attributes_type][$j]['type'] = "collection"; - self::_putDebug( "tag is: begCollection\n"); - self::_readAttributeName ($attributes_type,$j); - if (!$this->serveroutput->response[$attributes_type][$j]['name']) { // it is a multi-valued collection - $this->collection_depth ++; - $this->index --; - $this->collection_nbr[$this->collection_depth] ++; - } else { - $this->collection_depth ++; - if ($this->collection_depth == 0) - $this->collection = (object) 'collection'; - if (array_key_exists($this->collection_depth,$this->collection_nbr)) - $this->collection_nbr[$this->collection_depth] ++; - else - $this->collection_nbr[$this->collection_depth] = 0; - unset($this->end_collection); - - } - self::_readValue ("begCollection",$attributes_type,$j); - break; - case "endCollection": //RFC3382 (BLIND CODE) - $this->serveroutput->response[$attributes_type][$j]['type'] = "collection"; - self::_putDebug( "tag is: endCollection\n"); - self::_readAttributeName ($attributes_type,$j,0); - self::_readValue ('name',$attributes_type,$j,0); - $this->collection_depth --; - $this->collection_key[$this->collection_depth] = 0; - $this->end_collection = true; - break; - case "memberAttrName": // RFC3382 (BLIND CODE) - $this->serveroutput->response[$attributes_type][$j]['type'] = "memberAttrName"; - $this->index -- ; - self::_putDebug( "tag is: memberAttrName\n"); - self::_readCollection ($attributes_type,$j); - break; - - default: - $this->collection_depth = -1; - $this->collection_key = array(); - $this->collection_nbr = array(); - $this->serveroutput->response[$attributes_type][$j]['type'] = $tag; - self::_putDebug( "tag is: $tag\n"); - $attribute_name = self::_readAttributeName ($attributes_type,$j); - if (!$attribute_name) - $attribute_name = $this->attribute_name; - else - $this->attribute_name = $attribute_name; - $value = self::_readValue ($tag,$attributes_type,$j); - $this->serveroutput->response[$attributes_type][$j]['value'] = - self::_interpretAttribute($attribute_name,$tag,$this->serveroutput->response[$attributes_type][$j]['value']); - break; - - } - return; - } - // }}} - - // {{{ _readTag($tag) - protected function _readTag($tag) { - - switch ($tag) { - case 0x10: - $tag = "unsupported"; - break; - case 0x11: - $tag = "reserved for 'default'"; - break; - case 0x12: - $tag = "unknown"; - break; - case 0x13: - $tag = "no-value"; - break; - case 0x15: // RFC 3380 - $tag = "not-settable"; - break; - case 0x16: // RFC 3380 - $tag = "delete-attribute"; - break; - case 0x17: // RFC 3380 - $tag = "admin-define"; - break; - case 0x20: - $tag = "IETF reserved (generic integer)"; - break; - case 0x21: - $tag = "integer"; - break; - case 0x22: - $tag = "boolean"; - break; - case 0x23: - $tag = "enum"; - break; - case 0x30: - $tag = "octetString"; - break; - case 0x31: - $tag = "datetime"; - break; - case 0x32: - $tag = "resolution"; - break; - case 0x33: - $tag = "rangeOfInteger"; - break; - case 0x34: //RFC3382 (BLIND CODE) - $tag = "begCollection"; - break; - case 0x35: - $tag = "textWithLanguage"; - break; - case 0x36: - $tag = "nameWithLanguage"; - break; - case 0x37: //RFC3382 (BLIND CODE) - $tag = "endCollection"; - break; - case 0x40: - $tag = "IETF reserved text string"; - break; - case 0x41: - $tag = "textWithoutLanguage"; - break; - case 0x42: - $tag = "nameWithoutLanguage"; - break; - case 0x43: - $tag = "IETF reserved for future"; - break; - case 0x44: - $tag = "keyword"; - break; - case 0x45: - $tag = "uri"; - break; - case 0x46: - $tag = "uriScheme"; - break; - case 0x47: - $tag = "charset"; - break; - case 0x48: - $tag = "naturalLanguage"; - break; - case 0x49: - $tag = "mimeMediaType"; - break; - case 0x4A: // RFC3382 (BLIND CODE) - $tag = "memberAttrName"; - break; - case 0x7F: - $tag = "extended type"; - break; - default: - - if ($tag >= 0x14 && $tag < 0x15 && $tag > 0x17 && $tag <= 0x1f) - $tag = "out-of-band"; - elseif (0x24 <= $tag && $tag <= 0x2f) - $tag = "new integer type"; - elseif (0x38 <= $tag && $tag <= 0x3F) - $tag = "new octet-stream type"; - elseif (0x4B <= $tag && $tag <= 0x5F) - $tag = "new character string type"; - elseif ((0x60 <= $tag && $tag < 0x7f) || $tag >= 0x80 ) - $tag = "IETF reserved for future"; - else - $tag = sprintf("UNKNOWN: 0x%x (%u)",$tag,$tag); - - break; } - return $tag; - } - // }}} + } + } - // {{{ _readCollection($attributes_type,$j,&$collection) - protected function _readCollection($attributes_type,$j) { - + $this->serveroutput->response = array(); + $this->jobs_attributes = new \stdClass(); + for ($job_nbr = 0 ; $job_nbr <= $job ; $job_nbr ++) + { + $job_index = "job_".$job_nbr; + $this->jobs_attributes->$job_index = new \stdClass(); + for ($i = 0 ; $i < count($this->parsed[$job_nbr]) ; $i ++) + { + $name = $this->parsed[$job_nbr][$i]['name']; + $php_name = str_replace('-','_',$name); + $type = $this->parsed[$job_nbr][$i]['type']; + $range = $this->parsed[$job_nbr][$i]['range']; + $this->jobs_attributes->$job_index->$php_name = new \stdClass(); + $this->jobs_attributes->$job_index->$php_name->_type = $type; + $this->jobs_attributes->$job_index->$php_name->_range = $range; + for ($j = 0 ; $j < (count($this->parsed[$job_nbr][$i]) - 3) ; $j ++) + { + # This causes incorrect parsing of integer job attributes. + # 2010-08-16 + # bpkroth + #$value = self::_interpretAttribute($name,$type,$this->parsed[$job_nbr][$i][$j]); + $value = $this->parsed[$job_nbr][$i][$j]; + $index = '_value'.$j; + $this->jobs_attributes->$job_index->$php_name->$index = $value; + } + } + } + + $this->parsed = array(); + } + + protected function _readAttribute($attributes_type) + { + $tag = ord($this->serveroutput->body[$this->_parsing->offset]); + + $this->_parsing->offset += 1; + $j = $this->index; + + $tag = self::_readTag($tag); + + switch ($tag) + { + case "begCollection": //RFC3382 (BLIND CODE) + if ($this->end_collection) + { + $this->index --; + } + $this->end_collection = false; + $this->serveroutput->response[$attributes_type][$j]['type'] = "collection"; + self::_putDebug( "tag is: begCollection\n"); + self::_readAttributeName ($attributes_type,$j); + if (!$this->serveroutput->response[$attributes_type][$j]['name']) + { // it is a multi-valued collection + $this->collection_depth ++; + $this->index --; + $this->collection_nbr[$this->collection_depth] ++; + } + else + { + $this->collection_depth ++; + if ($this->collection_depth == 0) + { + $this->collection = (object) 'collection'; + } + if (array_key_exists($this->collection_depth,$this->collection_nbr)) + { + $this->collection_nbr[$this->collection_depth] ++; + } + else + { + $this->collection_nbr[$this->collection_depth] = 0; + } + unset($this->end_collection); + } + self::_readValue ("begCollection",$attributes_type,$j); + break; + case "endCollection": //RFC3382 (BLIND CODE) + $this->serveroutput->response[$attributes_type][$j]['type'] = "collection"; + self::_putDebug( "tag is: endCollection\n"); + self::_readAttributeName ($attributes_type,$j,0); + self::_readValue ('name',$attributes_type,$j,0); + $this->collection_depth --; + $this->collection_key[$this->collection_depth] = 0; + $this->end_collection = true; + break; + case "memberAttrName": // RFC3382 (BLIND CODE) + $this->serveroutput->response[$attributes_type][$j]['type'] = "memberAttrName"; + $this->index -- ; + self::_putDebug( "tag is: memberAttrName\n"); + self::_readCollection ($attributes_type,$j); + break; + + default: + $this->collection_depth = -1; + $this->collection_key = array(); + $this->collection_nbr = array(); + $this->serveroutput->response[$attributes_type][$j]['type'] = $tag; + self::_putDebug( "tag is: $tag\n"); + $attribute_name = self::_readAttributeName ($attributes_type,$j); + if (!$attribute_name) + { + $attribute_name = $this->attribute_name; + } + else + { + $this->attribute_name = $attribute_name; + } + $value = self::_readValue ($tag,$attributes_type,$j); + $this->serveroutput->response[$attributes_type][$j]['value'] = + self::_interpretAttribute($attribute_name,$tag,$this->serveroutput->response[$attributes_type][$j]['value']); + break; + } + return; + } + + protected function _readTag($tag) + { + switch ($tag) + { + case 0x10: + $tag = "unsupported"; + break; + case 0x11: + $tag = "reserved for 'default'"; + break; + case 0x12: + $tag = "unknown"; + break; + case 0x13: + $tag = "no-value"; + break; + case 0x15: // RFC 3380 + $tag = "not-settable"; + break; + case 0x16: // RFC 3380 + $tag = "delete-attribute"; + break; + case 0x17: // RFC 3380 + $tag = "admin-define"; + break; + case 0x20: + $tag = "IETF reserved (generic integer)"; + break; + case 0x21: + $tag = "integer"; + break; + case 0x22: + $tag = "boolean"; + break; + case 0x23: + $tag = "enum"; + break; + case 0x30: + $tag = "octetString"; + break; + case 0x31: + $tag = "datetime"; + break; + case 0x32: + $tag = "resolution"; + break; + case 0x33: + $tag = "rangeOfInteger"; + break; + case 0x34: //RFC3382 (BLIND CODE) + $tag = "begCollection"; + break; + case 0x35: + $tag = "textWithLanguage"; + break; + case 0x36: + $tag = "nameWithLanguage"; + break; + case 0x37: //RFC3382 (BLIND CODE) + $tag = "endCollection"; + break; + case 0x40: + $tag = "IETF reserved text string"; + break; + case 0x41: + $tag = "textWithoutLanguage"; + break; + case 0x42: + $tag = "nameWithoutLanguage"; + break; + case 0x43: + $tag = "IETF reserved for future"; + break; + case 0x44: + $tag = "keyword"; + break; + case 0x45: + $tag = "uri"; + break; + case 0x46: + $tag = "uriScheme"; + break; + case 0x47: + $tag = "charset"; + break; + case 0x48: + $tag = "naturalLanguage"; + break; + case 0x49: + $tag = "mimeMediaType"; + break; + case 0x4A: // RFC3382 (BLIND CODE) + $tag = "memberAttrName"; + break; + case 0x7F: + $tag = "extended type"; + break; + default: + if ($tag >= 0x14 && $tag < 0x15 && $tag > 0x17 && $tag <= 0x1f) + { + $tag = "out-of-band"; + } + elseif (0x24 <= $tag && $tag <= 0x2f) + { + $tag = "new integer type"; + } + elseif (0x38 <= $tag && $tag <= 0x3F) + { + $tag = "new octet-stream type"; + } + elseif (0x4B <= $tag && $tag <= 0x5F) + { + $tag = "new character string type"; + } + elseif ((0x60 <= $tag && $tag < 0x7f) || $tag >= 0x80 ) + { + $tag = "IETF reserved for future"; + } + else + { + $tag = sprintf("UNKNOWN: 0x%x (%u)",$tag,$tag); + } + break; + } + + return $tag; + } + + protected function _readCollection($attributes_type,$j) + { $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); - + $this->_parsing->offset += 2; - + self::_putDebug( "Collection name_length ". $name_length ."\n"); - + $name = ''; - for ($i = 0; $i < $name_length; $i++) { + for ($i = 0; $i < $name_length; $i++) + { $name .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; if ($this->_parsing->offset > strlen($this->serveroutput->body)) + { return; } - + } + $collection_name = $name; - + $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); $this->_parsing->offset += 2; - + self::_putDebug( "Attribute name_length ". $name_length ."\n"); - + $name = ''; - for ($i = 0; $i < $name_length; $i++) { + for ($i = 0; $i < $name_length; $i++) + { $name .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; if ($this->_parsing->offset > strlen($this->serveroutput->body)) + { return; } - + } + $attribute_name = $name; - if ($attribute_name == "") { + if ($attribute_name == "") + { $attribute_name = $this->last_attribute_name; $this->collection_key[$this->collection_depth] ++; - } else { + } + else + { $this->collection_key[$this->collection_depth] = 0; } $this->last_attribute_name = $attribute_name; - + self::_putDebug( "Attribute name ".$name."\n"); - + $tag = self::_readTag(ord($this->serveroutput->body[$this->_parsing->offset])); $this->_parsing->offset ++; - + $type = $tag; - + $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); $this->_parsing->offset += 2; - + self::_putDebug( "Collection2 name_length ". $name_length ."\n"); - + $name = ''; - for ($i = 0; $i < $name_length; $i++) { + for ($i = 0; $i < $name_length; $i++) + { $name .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; if ($this->_parsing->offset > strlen($this->serveroutput->body)) + { return; } - + } + $collection_value = $name; $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); - + self::_putDebug( "Collection value_length ".$this->serveroutput->body[ $this->_parsing->offset] . $this->serveroutput->body[$this->_parsing->offset + 1] .": " . $value_length . " "); - + $this->_parsing->offset += 2; - + $value = ''; - for ($i = 0; $i < $value_length; $i++) { - + for ($i = 0; $i < $value_length; $i++) + { if ($this->_parsing->offset >= strlen($this->serveroutput->body)) + { return; + } $value .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; - - } - + } + $object = &$this->collection; - for ($i = 0 ; $i <= $this->collection_depth ; $i ++) { + for ($i = 0 ; $i <= $this->collection_depth ; $i ++) + { $indice = "_indice".$this->collection_nbr[$i]; if (!isset($object->$indice)) + { $object->$indice = (object) 'indice'; - $object = &$object->$indice; } - + $object = &$object->$indice; + } + $value_key = "_value".$this->collection_key[$this->collection_depth]; $col_name_key = "_collection_name".$this->collection_key[$this->collection_depth]; $col_val_key = "_collection_value".$this->collection_key[$this->collection_depth]; - + $attribute_value = self::_interpretAttribute($attribute_name,$tag,$value); $attribute_name = str_replace('-','_',$attribute_name); - - + self::_putDebug( sprintf("Value: %s\n",$value)); $object->$attribute_name->_type = $type; $object->$attribute_name->$value_key = $attribute_value; $object->$attribute_name->$col_name_key = $collection_name; $object->$attribute_name->$col_val_key = $collection_value; - - $this->serveroutput->response[$attributes_type][$j]['value'] = $this->collection; - } - // }}} - - // {{{ _readAttributeName ($attributes_type,$j) - protected function _readAttributeName ($attributes_type,$j,$write=1) { + $this->serveroutput->response[$attributes_type][$j]['value'] = $this->collection; + } + + protected function _readAttributeName ($attributes_type,$j,$write=1) + { $name_length = ord($this->serveroutput->body[ $this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); $this->_parsing->offset += 2; - + self::_putDebug( "name_length ". $name_length ."\n"); - + $name = ''; - for ($i = 0; $i < $name_length; $i++) { + for ($i = 0; $i < $name_length; $i++) + { if ($this->_parsing->offset >= strlen($this->serveroutput->body)) + { return; + } $name .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; - } - + } + if($write) - $this->serveroutput->response[$attributes_type][$j]['name'] = $name; + { + $this->serveroutput->response[$attributes_type][$j]['name'] = $name; + } self::_putDebug( "name " . $name . "\n"); - - return $name; + + return $name; } - // }}} - - // {{{ _readValue ($type,$attributes_type,$j) - protected function _readValue ($type,$attributes_type,$j,$write=1) { + protected function _readValue ($type,$attributes_type,$j,$write=1) + { $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); @@ -1219,116 +1342,130 @@ class PrintIPP extends BasicIPP { .": " . $value_length . " "); - + $this->_parsing->offset += 2; - + $value = ''; - for ($i = 0; $i < $value_length; $i++) { - + for ($i = 0; $i < $value_length; $i++) + { if ($this->_parsing->offset >= strlen($this->serveroutput->body)) + { return; + } $value .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; - } - + self::_putDebug( sprintf("Value: %s\n",$value)); - + if ($write) - $this->serveroutput->response[$attributes_type][$j]['value'] = $value; + { + $this->serveroutput->response[$attributes_type][$j]['value'] = $value; + } - return $value; + return $value; } - // }}} - // {{{ _parseAttributes() - protected function _parseAttributes() { - + protected function _parseAttributes() + { $k = -1; + $l = 0; for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) + { for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++) - if (!empty($this->serveroutput->response[$i][$j]['name'])) { + { + if (!empty($this->serveroutput->response[$i][$j]['name'])) + { $k++; $l = 0; $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes']; $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name']; $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type']; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } else { + } + else + { $l ++; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } + } + } + } $this->serveroutput->response = array(); - $this->attributes = new stdClass(); - for ($i = 0 ; $i < count($this->parsed) ; $i ++) { + $this->attributes = new \stdClass(); + for ($i = 0 ; $i < count($this->parsed) ; $i ++) + { $name = $this->parsed[$i]['name']; $php_name = str_replace('-','_',$name); $type = $this->parsed[$i]['type']; $range = $this->parsed[$i]['range']; - $this->attributes->$php_name = new stdClass(); + $this->attributes->$php_name = new \stdClass(); $this->attributes->$php_name->_type = $type; $this->attributes->$php_name->_range = $range; - for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) { + for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) + { $value = $this->parsed[$i][$j]; $index = '_value'.$j; $this->attributes->$php_name->$index = $value; } } - + $this->parsed = array(); - } - // }}} - - // {{{ _parseJobAttributes() - protected function _parseJobAttributes() { + protected function _parseJobAttributes() + { //if (!preg_match('#successful#',$this->serveroutput->status)) // return false; - $k = -1; + $l = 0; for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) + { for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++) - if (!empty($this->serveroutput->response[$i][$j]['name'])) { + { + if (!empty($this->serveroutput->response[$i][$j]['name'])) + { $k++; $l = 0; $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes']; $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name']; $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type']; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } else { + } + else + { $l ++; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } - + } + } + } + $this->serveroutput->response = array(); - - $this->job_attributes = new stdClass(); - for ($i = 0 ; $i < count($this->parsed) ; $i ++) { + + $this->job_attributes = new \stdClass(); + for ($i = 0 ; $i < count($this->parsed) ; $i ++) + { $name = $this->parsed[$i]['name']; $php_name = str_replace('-','_',$name); $type = $this->parsed[$i]['type']; $range = $this->parsed[$i]['range']; - $this->job_attributes->$php_name = new stdClass(); + $this->job_attributes->$php_name = new \stdClass(); $this->job_attributes->$php_name->_type = $type; $this->job_attributes->$php_name->_range = $range; - for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) { + for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) + { $value = $this->parsed[$i][$j]; $index = '_value'.$j; $this->job_attributes->$php_name->$index = $value; } } - - $this->parsed = array(); - - - } - // }}} - // {{{ _interpretAttribute($attribute_name,$type,$value) - protected function _interpretAttribute($attribute_name,$type,$value) { - - switch ($type) { + $this->parsed = array(); + } + + protected function _interpretAttribute($attribute_name,$type,$value) + { + switch ($type) + { case "integer": $value = self::_interpretInteger($value); break; @@ -1338,9 +1475,13 @@ class PrintIPP extends BasicIPP { case 'boolean': $value = ord($value); if ($value == 0x00) + { $value = 'false'; + } else + { $value = 'true'; + } break; case 'datetime': $value = self::_interpretDateTime($value); @@ -1351,7 +1492,8 @@ class PrintIPP extends BasicIPP { case 'resolution': $unit = $value[8]; $value = self::_interpretRangeOfInteger(substr($value,0,8)); - switch($unit) { + switch($unit) + { case chr(0x03): $unit = "dpi"; break; @@ -1363,31 +1505,27 @@ class PrintIPP extends BasicIPP { break; default: break; - } - return $value; + } + return $value; } - // }}} - - // {{{ _interpretRangeOfInteger($value) - protected function _interpretRangeOfInteger($value) { - + + protected function _interpretRangeOfInteger($value) + { $value_parsed = 0; $integer1 = $integer2 = 0; - + $halfsize = strlen($value) / 2; - + $integer1 = self::_interpretInteger(substr($value,0,$halfsize)); $integer2 = self::_interpretInteger(substr($value,$halfsize,$halfsize)); - + $value_parsed = sprintf('%s-%s',$integer1,$integer2); - - - return $value_parsed; + + return $value_parsed; } - // }}} - - // {{{ _interpretDateTime($date) { - protected function _interpretDateTime($date) { + + protected function _interpretDateTime($date) + { $year = self::_interpretInteger(substr($date,0,2)); $month = self::_interpretInteger(substr($date,2,1)); $day = self::_interpretInteger(substr($date,3,1)); @@ -1397,21 +1535,21 @@ class PrintIPP extends BasicIPP { $direction = substr($date,8,1); $hours_from_utc = self::_interpretInteger(substr($date,9,1)); $minutes_from_utc = self::_interpretInteger(substr($date,10,1)); - + $date = sprintf('%s-%s-%s %s:%s:%s %s%s:%s',$year,$month,$day,$hour,$minute,$second,$direction,$hours_from_utc,$minutes_from_utc); - return $date; - } - // }}} - - // {{{ _interpretEnum() - protected function _interpretEnum($attribute_name,$value) { - + return $date; + } + + protected function _interpretEnum($attribute_name,$value) + { $value_parsed = self::_interpretInteger($value); - - switch ($attribute_name) { + + switch ($attribute_name) + { case 'job-state': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'pending'; break; @@ -1433,14 +1571,17 @@ class PrintIPP extends BasicIPP { case 0x09: $value = 'completed'; break; - } + } if ($value_parsed > 0x09) + { $value = sprintf('Unknown(IETF standards track "job-state" reserved): 0x%x',$value_parsed); + } break; case 'print-quality': case 'print-quality-supported': case 'print-quality-default': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'draft'; break; @@ -1453,7 +1594,8 @@ class PrintIPP extends BasicIPP { } break; case 'printer-state': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'idle'; break; @@ -1463,13 +1605,16 @@ class PrintIPP extends BasicIPP { case 0x05: $value = 'stopped'; break; - } + } if ($value_parsed > 0x05) + { $value = sprintf('Unknown(IETF standards track "printer-state" reserved): 0x%x',$value_parsed); + } break; - + case 'operations-supported': - switch($value_parsed) { + switch($value_parsed) + { case 0x0000: case 0x0001: $value = sprintf('Unknown(reserved) : %s',ord($value)); @@ -1602,20 +1747,31 @@ class PrintIPP extends BasicIPP { break; } if ($value_parsed > 0x002B && $value_parsed <= 0x3FFF) + { $value = sprintf('Unknown(IETF standards track operations reserved): 0x%x',$value_parsed); - elseif ($value_parsed >= 0x4000 && $value_parsed <= 0x8FFF) { - if (method_exists($this,'_getEnumVendorExtensions')) { + } + elseif ($value_parsed >= 0x4000 && $value_parsed <= 0x8FFF) + { + if (method_exists($this,'_getEnumVendorExtensions')) + { $value = $this->_getEnumVendorExtensions($value_parsed); - } else + } + else + { $value = sprintf('Unknown(Vendor extension for operations): 0x%x',$value_parsed); - } elseif ($value_parsed > 0x8FFF) + } + } + elseif ($value_parsed > 0x8FFF) + { $value = sprintf('Unknown operation (should not exists): 0x%x',$value_parsed); - + } + break; case 'finishings': case 'finishings-default': case 'finishings-supported': - switch ($value_parsed) { + switch ($value_parsed) + { case 3: $value = 'none'; break; @@ -1673,15 +1829,18 @@ class PrintIPP extends BasicIPP { case 31: $value = 'staple-dual-bottom'; break; - } + } if ($value_parsed > 31) + { $value = sprintf('Unknown(IETF standards track "finishing" reserved): 0x%x',$value_parsed); + } break; - + case 'orientation-requested': case 'orientation-requested-supported': case 'orientation-requested-default': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'portrait'; break; @@ -1694,77 +1853,87 @@ class PrintIPP extends BasicIPP { case 0x06: $value = 'reverse-portrait'; break; - } + } if ($value_parsed > 0x06) + { $value = sprintf('Unknown(IETF standards track "orientation" reserved): 0x%x',$value_parsed); + } break; - + default: break; - } - return $value; + } + return $value; } - // }}} - - // {{{ _getJobId () - protected function _getJobId () { - + + protected function _getJobId () + { if (!isset($this->serveroutput->response)) + { $this->jobs = array_merge($this->jobs,array('NO JOB')); - + } + $jobfinded = false; for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++) + { if (($this->serveroutput->response[$i]['attributes']) == "job-attributes") + { for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) - if ($this->serveroutput->response[$i][$j]['name'] == "job-id") { + { + if ($this->serveroutput->response[$i][$j]['name'] == "job-id") + { $this->last_job = $this->serveroutput->response[$i][$j]['value']; $this->jobs = array_merge($this->jobs,array($this->serveroutput->response[$i][$j]['value'])); return; - - } - + } + } + } + } } - // }}} - - // {{{ _getJobUri () - protected function _getJobUri () { + protected function _getJobUri () + { if (!isset($this->jobs_uri)) + { $this->jobs_uri = array(); - + } + $jobfinded = false; for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++) + { if (($this->serveroutput->response[$i]['attributes']) == "job-attributes") + { for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) - if ($this->serveroutput->response[$i][$j]['name'] == "job-uri") { + { + if ($this->serveroutput->response[$i][$j]['name'] == "job-uri") + { $this->last_job = $this->serveroutput->response[$i][$j]['value']; $this->jobs_uri = array_merge($this->jobs_uri,array($this->last_job)); return; - - } + } + } + } + } $this->last_job = ''; - } - // }}} - - // {{{ _parseResponse () - protected function _parseResponse () { + + protected function _parseResponse () + { $j = -1; $this->index = 0; - for ($i = $this->_parsing->offset; $i < strlen($this->serveroutput->body) ; $i = $this->_parsing->offset) { - - + for ($i = $this->_parsing->offset; $i < strlen($this->serveroutput->body) ; $i = $this->_parsing->offset) + { $tag = ord($this->serveroutput->body[$this->_parsing->offset]); - - - if ($tag > 0x0F) { - + + if ($tag > 0x0F) + { self::_readAttribute($j); $this->index ++; continue; - } + } - switch ($tag) { + switch ($tag) + { case 0x01: $j += 1; $this->serveroutput->response[$j]['attributes'] = "operation-attributes"; @@ -1782,7 +1951,9 @@ class PrintIPP extends BasicIPP { $this->serveroutput->response[$j]['attributes'] = "end-of-attributes"; self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n"); if ($this->alert_on_end_tag === 1) + { echo "END tag OK
"; + } $this->response_completed[(count($this->response_completed) -1)] = "completed"; return; case 0x04: @@ -1803,21 +1974,16 @@ class PrintIPP extends BasicIPP { $this->index = 0; $this->_parsing->offset += 1; break; - } - - self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n\n\n"); - - } - return; + } + + self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n\n\n"); + } + return; } - // }}} - - - /* // NOTICE : HAVE TO READ AGAIN RFC 2911 TO SEE IF IT IS PART OF SERVER'S RESPONSE (CUPS DO NOT) - // {{{ _getPrinterUri () + protected function _getPrinterUri () { for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++) @@ -1833,32 +1999,43 @@ class PrintIPP extends BasicIPP { $this->printers_uri = array_merge($this->printers_uri,array('')); } - // }}} + */ -// REQUEST BUILDING - - // {{{ _stringCancel () - protected function _stringCancel ($job_uri) { + // REQUEST BUILDING + protected function _stringCancel ($job_uri) + { if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); + { + self::setCharset(); + } if (!isset($this->setup->datatype)) + { self::setBinary(); + } if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!$this->requesting_user) + { self::setUserName(); + } if (!isset($this->meta->message)) + { $this->meta->message = ''; + } self::_setOperationId(); - + self::_setJobUri($job_uri); - + if (!isset($this->error_generation->request_body_malformed)) + { $this->error_generation->request_body_malformed = ""; - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x08) // cancel-Job | operation-id . $this->meta->operation_id // request-id @@ -1874,16 +2051,4 @@ class PrintIPP extends BasicIPP { self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); return TRUE; } - // }}} - - -}; - -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ -?> +} diff --git a/htdocs/includes/printipp/http_class.php b/htdocs/includes/printipp/http_class.php index 569d4f6648f..30bb33d663b 100644 --- a/htdocs/includes/printipp/http_class.php +++ b/htdocs/includes/printipp/http_class.php @@ -29,7 +29,7 @@ */ /** * This class is intended to implement a subset of Hyper Text Transfer Protocol - * (HTTP/1.1) on client side  (currently: POST operation), with file streaming + * (HTTP/1.1) on client side (currently: POST operation), with file streaming * capability. * * It can perform Basic and Digest authentication. @@ -66,48 +66,58 @@ ************************/ class httpException extends Exception { - protected $errno; - public function __construct ($msg, $errno = null) - { - parent::__construct ($msg); - $this->errno = $errno; - } - public function getErrorFormatted () - { - return sprintf ("[http_class]: %s -- "._(" file %s, line %s"), - $this->getMessage (), $this->getFile (), $this->getLine ()); - } - public function getErrno () - { - return $this->errno; - } + protected $errno; + + public function __construct ($msg, $errno = null) + { + parent::__construct ($msg); + $this->errno = $errno; + } + + public function getErrorFormatted () + { + return sprintf ("[http_class]: %s -- "._(" file %s, line %s"), + $this->getMessage (), $this->getFile (), $this->getLine ()); + } + + public function getErrno () + { + return $this->errno; + } } function error2string($value) { - $level_names = array( - E_ERROR => 'E_ERROR', - E_WARNING => 'E_WARNING', - E_PARSE => 'E_PARSE', - E_NOTICE => 'E_NOTICE', - E_CORE_ERROR => 'E_CORE_ERROR', - E_CORE_WARNING => 'E_CORE_WARNING', - E_COMPILE_ERROR => 'E_COMPILE_ERROR', - E_COMPILE_WARNING => 'E_COMPILE_WARNING', - E_USER_ERROR => 'E_USER_ERROR', - E_USER_WARNING => 'E_USER_WARNING', - E_USER_NOTICE => 'E_USER_NOTICE' - ); - if(defined('E_STRICT')) $level_names[E_STRICT]='E_STRICT'; - $levels=array(); - if(($value&E_ALL)==E_ALL) - { - $levels[]='E_ALL'; - $value&=~E_ALL; - } - foreach($level_names as $level=>$name) - if(($value&$level)==$level) $levels[]=$name; - return implode(' | ',$levels); + $level_names = array( + E_ERROR => 'E_ERROR', + E_WARNING => 'E_WARNING', + E_PARSE => 'E_PARSE', + E_NOTICE => 'E_NOTICE', + E_CORE_ERROR => 'E_CORE_ERROR', + E_CORE_WARNING => 'E_CORE_WARNING', + E_COMPILE_ERROR => 'E_COMPILE_ERROR', + E_COMPILE_WARNING => 'E_COMPILE_WARNING', + E_USER_ERROR => 'E_USER_ERROR', + E_USER_WARNING => 'E_USER_WARNING', + E_USER_NOTICE => 'E_USER_NOTICE' + ); + if(defined('E_STRICT')) { + $level_names[E_STRICT]='E_STRICT'; + } + $levels=array(); + if(($value&E_ALL)==E_ALL) + { + $levels[]='E_ALL'; + $value&=~E_ALL; + } + foreach($level_names as $level=>$name) + { + if(($value&$level)==$level) + { + $levels[]=$name; + } + } + return implode(' | ',$levels); } /*********************** @@ -117,499 +127,486 @@ function error2string($value) ************************/ class http_class { - // variables declaration - public $debug; - public $html_debug; - public $timeout = 30; // time waiting for connection, seconds - public $data_timeout = 30; // time waiting for data, milliseconds - public $data_chunk_timeout = 1; // time waiting between data chunks, millisecond - public $force_multipart_form_post; - public $username; - public $password; - public $request_headers = array (); - public $request_body = "Not a useful information"; - public $status; - public $window_size = 1024; // chunk size of data - public $with_exceptions = 0; // compatibility mode for old scripts - public $port; - public $host; - private $default_port = 631; - private $headers; - private $reply_headers = array (); - private $reply_body = array (); - private $connection; - private $arguments; - private $bodystream = array (); - private $last_limit; - private $connected; - private $nc = 1; - private $user_agent = "PRINTIPP/0.81+CVS"; - private $readed_bytes = 0; + // variables declaration + public $debug; + public $html_debug; + public $timeout = 30; // time waiting for connection, seconds + public $data_timeout = 30; // time waiting for data, milliseconds + public $data_chunk_timeout = 1; // time waiting between data chunks, millisecond + public $force_multipart_form_post; + public $username; + public $password; + public $request_headers = array (); + public $request_body = "Not a useful information"; + public $status; + public $window_size = 1024; // chunk size of data + public $with_exceptions = 0; // compatibility mode for old scripts + public $port; + public $host; + private $default_port = 631; + private $headers; + private $reply_headers = array (); + private $reply_body = array (); + private $connection; + private $arguments; + private $bodystream = array (); + private $last_limit; + private $connected; + private $nc = 1; + private $user_agent = "PRINTIPP/0.81+CVS"; + private $readed_bytes = 0; - public function __construct () - { - true; - } - - /********************* - * - * Public functions - * - **********************/ - - public function GetRequestArguments ($url, &$arguments) - { - $this->arguments = array (); - $arguments["URL"] = $this->arguments["URL"] = $url; - $arguments["RequestMethod"] = $this->arguments["RequestMethod"] = "POST"; - $this->headers["Content-Length"] = 0; - $this->headers["Content-Type"] = "application/octet-stream"; - $this->headers["Host"] = $this->host; - $this->headers["User-Agent"] = $this->user_agent; - //$this->headers["Expect"] = "100-continue"; - - } - - public function Open ($arguments) - { - $this->connected = false; - $url = $arguments["URL"]; - $port = $this->default_port; - #$url = split (':', $url, 2); - $url = preg_split ('#:#', $url, 2); - $transport_type = $url[0]; - $unix = false; - switch ($transport_type) - { - case 'http': - $transport_type = 'tcp://'; - break; - - case 'https': - $transport_type = 'tls://'; - break; - - case 'unix': - $transport_type = 'unix://'; - $port = 0; - $unix = true; - break; - - default: - $transport_type = 'tcp://'; - break; - } - $url = $url[1]; - if (!$unix) - { - #$url = split ("/", preg_replace ("#^/{1,}#", '', $url), 2); - $url = preg_split ("#/#", preg_replace ("#^/{1,}#", '', $url), 2); - $url = $url[0]; - $port = $this->port; - $error = sprintf (_("Cannot resolve url: %s"), $url); - $ip = gethostbyname ($url); - $ip = @gethostbyaddr ($ip); - if (!$ip) - { - return $this->_HttpError ($error, E_USER_WARNING); - } - if (strstr ($url, ":")) // we got an ipv6 address - if (!strstr ($url, "[")) // it is not escaped - $url = sprintf ("[%s]", $url); - } - $this->connection = @fsockopen ($transport_type.$url, $port, $errno, $errstr, $this->timeout); - $error = - sprintf (_('Unable to connect to "%s%s port %s": %s'), $transport_type, - $url, $port, $errstr); - if (!$this->connection) - { - return $this->_HttpError ($error, E_USER_WARNING); - } - $this->connected = true; - return array (true, "success"); - } - - public function SendRequest ($arguments) - { - $error = - sprintf (_('Streaming request failed to %s'), $arguments['RequestURI']); - $result = self::_StreamRequest ($arguments); - if (!$result[0]) - { - return $this->_HttpError ($error." ".$result[1], E_USER_WARNING); - } - self::_ReadReply (); - if (!preg_match ('#http/1.1 401 unauthorized#', $this->status)) - { - return array (true, "success"); - } - $headers = array_keys ($this->reply_headers); - $error = _("need authentication but no mechanism provided"); - if (!in_array ("www-authenticate", $headers)) - { - return $this->_HttpError ($error, E_USER_WARNING); - } - #$authtype = split (' ', $this->reply_headers["www-authenticate"]); - $authtype = preg_split ('# #', $this->reply_headers["www-authenticate"]); - $authtype = strtolower ($authtype[0]); - switch ($authtype) - { - case 'basic': - $pass = base64_encode ($this->user.":".$this->password); - $arguments["Headers"]["Authorization"] = "Basic ".$pass; - break; - - case 'digest': - $arguments["Headers"]["Authorization"] = self::_BuildDigest (); - break; - - default: - $error = - sprintf (_("need '%s' authentication mechanism, but have not"), - $authtype[0]); - return $this->_HttpError ($error, E_USER_WARNING); - break; - - } - self::Close (); - self::Open ($arguments); - $error = - sprintf (_ - ('Streaming request failed to %s after a try to authenticate'), - $url); - $result = self::_StreamRequest ($arguments); - if (!$result[0]) - { - return $this->_HttpError ($error.": ".$result[1], E_USER_WARNING); - } - self::_ReadReply (); - return array (true, "success"); - } - - public function ReadReplyHeaders (&$headers) - { - $headers = $this->reply_headers; - } - - public function ReadReplyBody (&$body, $chunk_size) - { - $body = substr ($this->reply_body, $this->last_limit, $chunk_size); - $this->last_limit += $chunk_size; - } - - public function Close () - { - if (!$this->connected) - return; - fclose ($this->connection); - } - - /********************* - * - * Private functions - * - *********************/ - - private function _HttpError ($msg, $level, $errno = null) - { - $trace = ''; - $backtrace = debug_backtrace; - foreach ($backtrace as $trace) - { - $trace .= sprintf ("in [file: '%s'][function: '%s'][line: %s];\n", $trace['file'], $trace['function'],$trace['line']); - } - $msg = sprintf ( '%s\n%s: [errno: %s]: %s', - $trace, error2string ($level), $errno, $msg); - if ($this->with_exceptions) - { - throw new httpException ($msg, $errno); - } - else - { - trigger_error ($msg, $level); - return array (false, $msg); - } - } - - private function _streamString ($string) - { - $success = fwrite ($this->connection, $string); - if (!$success) - { - return false; - } - return true; - } - - private function _StreamRequest ($arguments) - { - $this->status = false; - $this->reply_headers = array (); - $this->reply_body = ""; - if (!$this->connected) - { - return _HttpError (_("not connected"), E_USER_WARNING); - } - $this->arguments = $arguments; - $content_length = 0; - foreach ($this->arguments["BodyStream"] as $argument) - { - list ($type, $value) = each ($argument); - reset ($argument); - if ($type == "Data") - { - $length = strlen ($value); - } - elseif ($type == "File") - { - if (is_readable ($value)) + public function __construct () { - $length = filesize ($value); + true; } - else + + /********************* + * + * Public functions + * + **********************/ + + public function GetRequestArguments ($url, &$arguments) { - $length = 0; - return - _HttpError (sprintf (_("%s: file is not readable"), $value), - E_USER_WARNING); + $this->arguments = array (); + $this->arguments["URL"] = $arguments["URL"] = $url; + $this->arguments["RequestMethod"] = $arguments["RequestMethod"] = "POST"; + $this->headers["Content-Length"] = 0; + $this->headers["Content-Type"] = "application/octet-stream"; + $this->headers["Host"] = $this->host; + $this->headers["User-Agent"] = $this->user_agent; + //$this->headers["Expect"] = "100-continue"; } - } - else - { - $length = 0; - return - _HttpError (sprintf - (_("%s: not a valid argument for content"), $type), - E_USER_WARNING); - } - $content_length += $length; - } - $this->request_body = sprintf (_("%s Bytes"), $content_length); - $this->headers["Content-Length"] = $content_length; - $this->arguments["Headers"] = - array_merge ($this->headers, $this->arguments["Headers"]); - if ($this->arguments["RequestMethod"] != "POST") - { - return - _HttpError (sprintf - (_("%s: method not implemented"), - $arguments["RequestMethod"]), E_USER_WARNING); - } - $string = - sprintf ("POST %s HTTP/1.1\r\n", $this->arguments["RequestURI"]); - $this->request_headers[$string] = ''; - if (!$this->_streamString ($string)) - { - return _HttpError (_("Error while puts POST operation"), - E_USER_WARNING); - } - foreach ($this->arguments["Headers"] as $header => $value) - { - $string = sprintf ("%s: %s\r\n", $header, $value); - $this->request_headers[$header] = $value; - if (!$this->_streamString ($string)) - { - return _HttpError (_("Error while puts HTTP headers"), - E_USER_WARNING); - } - } - $string = "\r\n"; - if (!$this->_streamString ($string)) - { - return _HttpError (_("Error while ends HTTP headers"), - E_USER_WARNING); - } - foreach ($this->arguments["BodyStream"] as $argument) - { - list ($type, $value) = each ($argument); - reset ($argument); - if ($type == "Data") - { - $streamed_length = 0; - while ($streamed_length < strlen ($value)) + + public function Open ($arguments) { - $string = substr ($value, $streamed_length, $this->window_size); - if (!$this->_streamString ($string)) - { - return _HttpError (_("error while sending body data"), - E_USER_WARNING); - } - $streamed_length += $this->window_size; + $this->connected = false; + $url = $arguments["URL"]; + $port = $this->default_port; + #$url = split (':', $url, 2); + $url = preg_split ('#:#', $url, 2); + $transport_type = $url[0]; + $unix = false; + switch ($transport_type) + { + case 'http': + $transport_type = 'tcp://'; + break; + + case 'https': + $transport_type = 'tls://'; + break; + + case 'unix': + $transport_type = 'unix://'; + $port = 0; + $unix = true; + break; + + default: + $transport_type = 'tcp://'; + break; + } + $url = $url[1]; + if (!$unix) + { + #$url = split ("/", preg_replace ("#^/{1,}#", '', $url), 2); + $url = preg_split ("#/#", preg_replace ("#^/{1,}#", '', $url), 2); + $url = $url[0]; + $port = $this->port; + $error = sprintf (_("Cannot resolve url: %s"), $url); + $ip = gethostbyname ($url); + $ip = @gethostbyaddr ($ip); + if (!$ip) + { + return $this->_HttpError ($error, E_USER_WARNING); + } + if (strstr ($url, ":")) // we got an ipv6 address + { + if (!strstr ($url, "[")) // it is not escaped + { + $url = sprintf ("[%s]", $url); + } + } + } + $this->connection = @fsockopen ($transport_type.$url, $port, $errno, $errstr, $this->timeout); + $error = + sprintf (_('Unable to connect to "%s%s port %s": %s'), $transport_type, + $url, $port, $errstr); + if (!$this->connection) + { + return $this->_HttpError ($error, E_USER_WARNING); + } + $this->connected = true; + return array (true, "success"); } - } - elseif ($type == "File") - { - if (is_readable ($value)) + + public function SendRequest ($arguments) { - $file = fopen ($value, 'rb'); - while (!feof ($file)) - { - if (gettype ($block = @fread ($file, $this->window_size)) != - "string") - { - return _HttpError (_("cannot read file to upload"), - E_USER_WARNING); - } - if (!$this->_streamString ($block)) - { - return _HttpError (_("error while sending body data"), - E_USER_WARNING); - } - } + $error = + sprintf (_('Streaming request failed to %s'), $arguments['RequestURI']); + $result = self::_StreamRequest ($arguments); + if (!$result[0]) + { + return $this->_HttpError ($error." ".$result[1], E_USER_WARNING); + } + self::_ReadReply (); + if (!preg_match ('#http/1.1 401 unauthorized#', $this->status)) + { + return array (true, "success"); + } + $headers = array_keys ($this->reply_headers); + $error = _("need authentication but no mechanism provided"); + if (!in_array ("www-authenticate", $headers)) + { + return $this->_HttpError ($error, E_USER_WARNING); + } + #$authtype = split (' ', $this->reply_headers["www-authenticate"]); + $authtype = preg_split ('# #', $this->reply_headers["www-authenticate"]); + $authtype = strtolower ($authtype[0]); + switch ($authtype) + { + case 'basic': + $pass = base64_encode ($this->user.":".$this->password); + $arguments["Headers"]["Authorization"] = "Basic ".$pass; + break; + + case 'digest': + $arguments["Headers"]["Authorization"] = self::_BuildDigest (); + break; + + default: + $error = + sprintf (_("need '%s' authentication mechanism, but have not"), + $authtype[0]); + return $this->_HttpError ($error, E_USER_WARNING); + break; + } + self::Close (); + self::Open ($arguments); + + $error = sprintf(_('Streaming request failed to %s after a try to authenticate'), $arguments['RequestURI']); + $result = self::_StreamRequest ($arguments); + if (!$result[0]) + { + return $this->_HttpError ($error.": ".$result[1], E_USER_WARNING); + } + self::_ReadReply (); + return array (true, "success"); } - } - } - return array (true, "success"); - } - private function _ReadReply () - { - if (!$this->connected) - { - return array (false, _("not connected")); - } - $this->reply_headers = array (); - $this->reply_body = ""; - $headers = array (); - $body = ""; - while (!feof ($this->connection)) - { - $line = fgets ($this->connection, 1024); - if (strlen (trim($line)) == 0) - break; // \r\n => end of headers - if (preg_match ('#^[[:space:]]#', $line)) - { - $headers[-1] .= sprintf(' %s', trim ($line)); - continue; - } - $headers[] = trim ($line); - } - $this->status = isset ($headers[0]) ? strtolower ($headers[0]) : false; - foreach ($headers as $header) - { - $header = preg_split ("#: #", $header); - $header[0] = strtolower ($header[0]); - if ($header[0] !== "www-authenticate") - { - $header[1] = isset ($header[1]) ? strtolower ($header[1]) : ""; - } - if (!isset ($this->reply_headers[$header[0]])) - { - $this->reply_headers[$header[0]] = $header[1]; - } - } - self::_ReadStream (); - return true; - } + public function ReadReplyHeaders (&$headers) + { + $headers = $this->reply_headers; + } - private function _ReadStream () - { - if (! array_key_exists ("content-length", $this->reply_headers)) - { - stream_set_blocking($this->connection, 0); - $this->reply_body = stream_get_contents($this->connection); - return true; - } - stream_set_blocking($this->connection, 1); - $content_length = $this->reply_headers["content-length"]; - $this->reply_body = stream_get_contents($this->connection,$content_length); - return true; - } + public function ReadReplyBody (&$body, $chunk_size) + { + $body = substr ($this->reply_body, $this->last_limit, $chunk_size); + $this->last_limit += $chunk_size; + } - private function _BuildDigest () - { - $auth = $this->reply_headers["www-authenticate"]; - #list ($head, $auth) = split (" ", $auth, 2); - list ($head, $auth) = preg_split ("# #", $auth, 2); - #$auth = split (", ", $auth); - $auth = preg_split ("#, #", $auth); - foreach ($auth as $sheme) - { - #list ($sheme, $value) = split ('=', $sheme); - list ($sheme, $value) = preg_split ('#=#', $sheme); - $fields[$sheme] = trim (trim ($value), '"'); - } - $nc = sprintf ('%x', $this->nc); - $prepend = ""; - while ((strlen ($nc) + strlen ($prepend)) < 8) - $prependi .= "0"; - $nc = $prepend.$nc; - $cnonce = "printipp"; - $username = $this->user; - $password = $this->password; - $A1 = $username.":".$fields["realm"].":".$password; - if (array_key_exists ("algorithm", $fields)) - { - $algorithm = strtolower ($fields["algorithm"]); - switch ($algorithm) - { - case "md5": - break; + public function Close () + { + if (!$this->connected) + { + return; + } + fclose ($this->connection); + } - case "md5-sess": - $A1 = - $username.":".$fields["realm"].":".$password.":". - $fields['nonce'].":".$cnonce; - break; + /********************* + * + * Private functions + * + *********************/ - default: - return _HttpError( - sprintf (_("digest Authorization: algorithm '%s' not implemented"), - $algorithm), - E_USER_WARNING); - return false; - break; - } - } - $A2 = "POST:".$this->arguments["RequestURI"]; - if (array_key_exists ("qop", $fields)) - { - $qop = strtolower ($fields["qop"]); - #$qop = split (" ", $qop); - $qop = preg_split ("# #", $qop); - if (in_array ("auth", $qop)) - $qop = "auth"; - else - { - self::_HttpError( - sprintf (_("digest Authorization: algorithm '%s' not implemented"), - $qop), - E_USER_WARNING); - return false; - } - } - $response = md5 (md5 ($A1).":".$fields["nonce"].":".md5 ($A2)); - if (isset ($qop) && ($qop == "auth")) - { - $response = - md5 (md5 ($A1).":".$fields["nonce"].":".$nc.":".$cnonce.":".$qop. - ":".$A2); - } - $auth_scheme = - sprintf - ('Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"', - $username, $fields["realm"], $fields['nonce'], - $this->arguments["RequestURI"], $response); - if (isset ($algorithm)) - $auth_scheme .= sprintf (', algorithm="%s"', $algorithm); - if (isset ($qop)) - $auth_scheme .= sprintf (', cnonce="%s"', $cnonce); - if (array_key_exists ("opaque", $fields)) - $auth_scheme .= sprintf (', opaque="%s"', $fields['opaque']); - if (isset ($qop)) - $auth_scheme .= sprintf (', qop="%s"', $qop); - $auth_scheme .= sprintf (', nc=%s', $nc); - $this->nc++; - return $auth_scheme; - } + private function _HttpError ($msg, $level, $errno = null) + { + $trace = ''; + $backtrace = debug_backtrace(); + foreach ($backtrace as $trace) + { + $trace .= sprintf ("in [file: '%s'][function: '%s'][line: %s];\n", $trace['file'], $trace['function'],$trace['line']); + } + $msg = sprintf ( '%s\n%s: [errno: %s]: %s', + $trace, error2string ($level), $errno, $msg); + if ($this->with_exceptions) + { + throw new httpException ($msg, $errno); + } + else + { + trigger_error ($msg, $level); + return array (false, $msg); + } + } -}; + private function _streamString ($string) + { + $success = fwrite ($this->connection, $string); + if (!$success) + { + return false; + } + return true; + } -/* - * Local variables: - * mode: php - * tab-width: 2 - * c-basic-offset: 2 - * End: - */ -?> + private function _StreamRequest ($arguments) + { + $this->status = false; + $this->reply_headers = array (); + $this->reply_body = ""; + if (!$this->connected) + { + return $this->_HttpError (_("not connected"), E_USER_WARNING); + } + $this->arguments = $arguments; + $content_length = 0; + foreach ($this->arguments["BodyStream"] as $argument) + { + list ($type, $value) = each ($argument); + reset ($argument); + if ($type == "Data") + { + $length = strlen ($value); + } + elseif ($type == "File") + { + if (is_readable ($value)) + { + $length = filesize ($value); + } + else + { + $length = 0; + return $this->_HttpError (sprintf (_("%s: file is not readable"), $value), E_USER_WARNING); + } + } + else + { + $length = 0; + return $this->_HttpError (sprintf(_("%s: not a valid argument for content"), $type), E_USER_WARNING); + } + $content_length += $length; + } + $this->request_body = sprintf (_("%s Bytes"), $content_length); + $this->headers["Content-Length"] = $content_length; + $this->arguments["Headers"] = array_merge ($this->headers, $this->arguments["Headers"]); + if ($this->arguments["RequestMethod"] != "POST") + { + return $this->_HttpError (sprintf(_("%s: method not implemented"), $arguments["RequestMethod"]), E_USER_WARNING); + } + $string = sprintf ("POST %s HTTP/1.1\r\n", $this->arguments["RequestURI"]); + $this->request_headers[$string] = ''; + if (!$this->_streamString ($string)) + { + return $this->_HttpError (_("Error while puts POST operation"), E_USER_WARNING); + } + foreach ($this->arguments["Headers"] as $header => $value) + { + $string = sprintf ("%s: %s\r\n", $header, $value); + $this->request_headers[$header] = $value; + if (!$this->_streamString ($string)) + { + return $this->_HttpError (_("Error while puts HTTP headers"), E_USER_WARNING); + } + } + $string = "\r\n"; + if (!$this->_streamString ($string)) + { + return $this->_HttpError (_("Error while ends HTTP headers"), E_USER_WARNING); + } + foreach ($this->arguments["BodyStream"] as $argument) + { + list ($type, $value) = each ($argument); + reset ($argument); + if ($type == "Data") + { + $streamed_length = 0; + while ($streamed_length < strlen ($value)) + { + $string = substr ($value, $streamed_length, $this->window_size); + if (!$this->_streamString ($string)) + { + return $this->_HttpError (_("error while sending body data"), E_USER_WARNING); + } + $streamed_length += $this->window_size; + } + } + elseif ($type == "File") + { + if (is_readable ($value)) + { + $file = fopen ($value, 'rb'); + while (!feof ($file)) + { + if (gettype ($block = @fread ($file, $this->window_size)) != "string") + { + return $this->_HttpError (_("cannot read file to upload"), E_USER_WARNING); + } + if (!$this->_streamString ($block)) + { + return $this->_HttpError (_("error while sending body data"), E_USER_WARNING); + } + } + } + } + } + return array (true, "success"); + } + + private function _ReadReply () + { + if (!$this->connected) + { + return array (false, _("not connected")); + } + $this->reply_headers = array (); + $this->reply_body = ""; + $headers = array (); + $body = ""; + while (!feof ($this->connection)) + { + $line = fgets ($this->connection, 1024); + if (strlen (trim($line)) == 0) + { + break; + } // \r\n => end of headers + if (preg_match ('#^[[:space:]]#', $line)) + { + $headers[-1] .= sprintf(' %s', trim ($line)); + continue; + } + $headers[] = trim ($line); + } + $this->status = isset ($headers[0]) ? strtolower ($headers[0]) : false; + foreach ($headers as $header) + { + $header = preg_split ("#: #", $header); + $header[0] = strtolower ($header[0]); + if ($header[0] !== "www-authenticate") + { + $header[1] = isset ($header[1]) ? strtolower ($header[1]) : ""; + } + if (!isset ($this->reply_headers[$header[0]])) + { + $this->reply_headers[$header[0]] = $header[1]; + } + } + self::_ReadStream (); + return true; + } + + private function _ReadStream () + { + if (! array_key_exists ("content-length", $this->reply_headers)) + { + stream_set_blocking($this->connection, 0); + $this->reply_body = stream_get_contents($this->connection); + return true; + } + stream_set_blocking($this->connection, 1); + $content_length = $this->reply_headers["content-length"]; + $this->reply_body = stream_get_contents($this->connection,$content_length); + return true; + } + + private function _BuildDigest () + { + $auth = $this->reply_headers["www-authenticate"]; + #list ($head, $auth) = split (" ", $auth, 2); + list ($head, $auth) = preg_split ("# #", $auth, 2); + #$auth = split (", ", $auth); + $auth = preg_split ("#, #", $auth); + foreach ($auth as $sheme) + { + #list ($sheme, $value) = split ('=', $sheme); + list ($sheme, $value) = preg_split ('#=#', $sheme); + $fields[$sheme] = trim (trim ($value), '"'); + } + $nc = sprintf ('%x', $this->nc); + $prepend = ""; + while ((strlen ($nc) + strlen ($prepend)) < 8) + $prependi .= "0"; + $nc = $prepend.$nc; + $cnonce = "printipp"; + $username = $this->user; + $password = $this->password; + $A1 = $username.":".$fields["realm"].":".$password; + if (array_key_exists ("algorithm", $fields)) + { + $algorithm = strtolower ($fields["algorithm"]); + switch ($algorithm) + { + case "md5": + break; + + case "md5-sess": + $A1 = + $username.":".$fields["realm"].":".$password.":". + $fields['nonce'].":".$cnonce; + break; + + default: + return $this->_HttpError( + sprintf (_("digest Authorization: algorithm '%s' not implemented"), + $algorithm), + E_USER_WARNING); + return false; + break; + } + } + $A2 = "POST:".$this->arguments["RequestURI"]; + if (array_key_exists ("qop", $fields)) + { + $qop = strtolower ($fields["qop"]); + #$qop = split (" ", $qop); + $qop = preg_split ("# #", $qop); + if (in_array ("auth", $qop)) + { + $qop = "auth"; + } + else + { + self::_HttpError( + sprintf (_("digest Authorization: algorithm '%s' not implemented"), + $qop), + E_USER_WARNING); + return false; + } + } + $response = md5 (md5 ($A1).":".$fields["nonce"].":".md5 ($A2)); + if (isset ($qop) && ($qop == "auth")) + { + $response = + md5 (md5 ($A1).":".$fields["nonce"].":".$nc.":".$cnonce.":".$qop. + ":".$A2); + } + $auth_scheme = + sprintf + ('Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"', + $username, $fields["realm"], $fields['nonce'], + $this->arguments["RequestURI"], $response); + if (isset ($algorithm)) + { + $auth_scheme .= sprintf (', algorithm="%s"', $algorithm); + } + if (isset ($qop)) + { + $auth_scheme .= sprintf (', cnonce="%s"', $cnonce); + } + if (array_key_exists ("opaque", $fields)) + { + $auth_scheme .= sprintf (', opaque="%s"', $fields['opaque']); + } + if (isset ($qop)) + { + $auth_scheme .= sprintf (', qop="%s"', $qop); + } + $auth_scheme .= sprintf (', nc=%s', $nc); + $this->nc++; + return $auth_scheme; + } +} diff --git a/htdocs/install/mysql/data/llx_const.sql b/htdocs/install/mysql/data/llx_const.sql index 0c0a98355c0..3b627f3d99b 100644 --- a/htdocs/install/mysql/data/llx_const.sql +++ b/htdocs/install/mysql/data/llx_const.sql @@ -40,13 +40,13 @@ insert into llx_const (name, value, type, note, visible, entity) values ('SYSLOG insert into llx_const (name, value, type, note, visible, entity) values ('SYSLOG_FILE','DOL_DATA_ROOT/dolibarr.log','chaine','Directory where to write log file',0,0); insert into llx_const (name, value, type, note, visible, entity) values ('SYSLOG_LEVEL','7','chaine','Level of debug info to show',0,0); -insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_SMTP_SERVER','','chaine','Host or ip address for SMTP server',0,0); -insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_SMTP_PORT','','chaine','Port for SMTP server',0,0); - insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_UPLOAD_DOC','2048','chaine','Max size for file upload (0 means no upload allowed)',0,0); -- Hidden but specific to one entity insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MONNAIE','EUR','chaine','Monnaie',0,1); + +insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_SMTP_SERVER','','chaine','Host or ip address for SMTP server',0,1); +insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_SMTP_PORT','','chaine','Port for SMTP server',0,1); insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_EMAIL_FROM','robot@domain.com','chaine','EMail emetteur pour les emails automatiques Dolibarr',0,1); -- diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index cea731b9dc9..cb70f85a32c 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -26,14 +26,47 @@ create table llx_c_price_expression expression varchar(80) NOT NULL )ENGINE=innodb; +--create table for user conf of printing driver +CREATE TABLE llx_printing +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + datec datetime, + printer_name text NOT NULL, + printer_location text NOT NULL, + printer_id varchar(255) NOT NULL, + copy integer NOT NULL DEFAULT '1', + module varchar(16) NOT NULL, + driver varchar(16) NOT NULL, + userid integer +)ENGINE=innodb; + ALTER TABLE llx_product_fournisseur_price ADD fk_price_expression integer DEFAULT NULL; -- Taiwan VAT Rates insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 2131, 213, '5', '0', 'VAT 5%', 1); -- Add situation invoices -ALTER TABLE llx_facture ADD situation_cycle_ref integer; -ALTER TABLE llx_facture ADD situation_counter integer; -ALTER TABLE llx_facture ADD situation_final integer; -ALTER TABLE llx_facturedet ADD situation_percent real; -ALTER TABLE llx_facturedet ADD fk_prev_id integer; +ALTER TABLE llx_facture ADD COLUMN situation_cycle_ref smallint; +ALTER TABLE llx_facture ADD COLUMN situation_counter smallint; +ALTER TABLE llx_facture ADD COLUMN situation_final smallint; +ALTER TABLE llx_facturedet ADD COLUMN situation_percent real; +ALTER TABLE llx_facturedet ADD COLUMN fk_prev_id integer; + +-- Convert SMTP config to main entity, so new entities don't get the old values +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SENDMODE"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTP_PORT"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTP_SERVER"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTPS_ID"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTPS_PW"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_EMAIL_TLS"; + + +create table llx_bank_account_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_contrat.sql b/htdocs/install/mysql/tables/llx_contrat.sql index 5efbcdfe1fa..0e75c50305b 100644 --- a/htdocs/install/mysql/tables/llx_contrat.sql +++ b/htdocs/install/mysql/tables/llx_contrat.sql @@ -23,6 +23,7 @@ create table llx_contrat rowid integer AUTO_INCREMENT PRIMARY KEY, ref varchar(30), -- contrat reference ref_supplier varchar(30), -- suplier contract ref + ref_ext varchar(30), -- external contract ref entity integer DEFAULT 1 NOT NULL, -- multi company id tms timestamp, datec datetime, -- creation date diff --git a/htdocs/install/mysql/tables/llx_facture.sql b/htdocs/install/mysql/tables/llx_facture.sql index 144cd349dd6..eada5b46c2e 100644 --- a/htdocs/install/mysql/tables/llx_facture.sql +++ b/htdocs/install/mysql/tables/llx_facture.sql @@ -78,8 +78,8 @@ create table llx_facture import_key varchar(14), extraparams varchar(255), -- for stock other parameters with json format - situation_cycle_ref smallint UNSIGNED, -- situation cycle reference - situation_counter tinyint UNSIGNED, -- situation counter - situation_final boolean -- is the situation final ? + situation_cycle_ref smallint, -- situation cycle reference + situation_counter smallint, -- situation counter + situation_final smallint -- is the situation final ? )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_printer_ipp.sql b/htdocs/install/mysql/tables/llx_printing.sql similarity index 77% rename from htdocs/install/mysql/tables/llx_printer_ipp.sql rename to htdocs/install/mysql/tables/llx_printing.sql index a19e05587d6..451564ff74b 100644 --- a/htdocs/install/mysql/tables/llx_printer_ipp.sql +++ b/htdocs/install/mysql/tables/llx_printing.sql @@ -1,5 +1,6 @@ -- ============================================================================ --- Copyright (C) 2013 Florian HENRY +-- Copyright (C) 2013 Florian HENRY +-- Copyright (C) 2014 Frederic France -- -- 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 @@ -16,15 +17,16 @@ -- -- ============================================================================ -CREATE TABLE llx_printer_ipp +CREATE TABLE llx_printing ( rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp, - datec datetime, + tms timestamp, + datec datetime, printer_name text NOT NULL, printer_location text NOT NULL, - printer_uri varchar(255) NOT NULL, + printer_id varchar(255) NOT NULL, copy integer NOT NULL DEFAULT '1', module varchar(16) NOT NULL, - login varchar(32) NOT NULL + driver varchar(16) NOT NULL, + userid integer )ENGINE=innodb; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 2dda463b91c..04278f312aa 100755 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1040,7 +1040,7 @@ SendingMailSetup=Setup of sendings by email SendmailOptionNotComplete=Warning, on some Linux systems, to send email from your email, sendmail execution setup must contains option -ba (parameter mail.force_extra_parameters into your php.ini file). If some recipients never receive emails, try to edit this PHP parameter with mail.force_extra_parameters = -ba). PathToDocuments=Path to documents PathDirectory=Directory -SendmailOptionMayHurtBuggedMTA=Feature to send mails using method "PHP mail direct" will generate a mail message that might be not correctly parsed by some receiving mail servers. Result is that some mails can't be read by people hosted by thoose bugged platforms. It's case for some Internet providers (Ex: Orange in France). This is not a problem into Dolibarr nor into PHP but onto receiving mail server. You can however add option MAIN_FIX_FOR_BUGGED_MTA to 1 into setup - other to modify Dolibarr to avoid this. However, you may experience problem with other servers that respect strictly the SMTP standard. The other solution (recommanded) is to use the method "SMTP socket library" that has no disadvantages. +SendmailOptionMayHurtBuggedMTA=Feature to send mails using method "PHP mail direct" will generate a mail message that might be not correctly parsed by some receiving mail servers. Result is that some mails can't be read by people hosted by those bugged platforms. It's case for some Internet providers (Ex: Orange in France). This is not a problem into Dolibarr nor into PHP but onto receiving mail server. You can however add option MAIN_FIX_FOR_BUGGED_MTA to 1 into setup - other to modify Dolibarr to avoid this. However, you may experience problem with other servers that respect strictly the SMTP standard. The other solution (recommended) is to use the method "SMTP socket library" that has no disadvantages. TranslationSetup=Configuration de la traduction TranslationDesc=Choice of language visible on screen can be modified:
* Globally from menu Home - Setup - Display
* For user only from tab User display of user card (click on login on top of screen). TotalNumberOfActivatedModules=Total number of activated feature modules: %s @@ -1417,7 +1417,7 @@ AdvancedEditor=Advanced editor ActivateFCKeditor=Activate advanced editor for: FCKeditorForCompany=WYSIWIG creation/edition of elements description and note (except products/services) FCKeditorForProduct=WYSIWIG creation/edition of products/services description and note -FCKeditorForProductDetails=WYSIWIG creation/edition of products details lines for all entities (proposals, orders, invoices, etc...). Warning: Using this option for this case is seriously not recommanded as it can create problems with special characters and page formating when building PDF files. +FCKeditorForProductDetails=WYSIWIG creation/edition of products details lines for all entities (proposals, orders, invoices, etc...). Warning: Using this option for this case is seriously not recommended as it can create problems with special characters and page formating when building PDF files. FCKeditorForMailing= WYSIWIG creation/edition for mass eMailings (Tools->eMailing) FCKeditorForUserSignature=WYSIWIG creation/edition of user signature FCKeditorForMail=WYSIWIG creation/edition for all mail (except Outils->eMailing) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index bfded6f40e2..0f41a43c90f 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -260,6 +260,7 @@ days=days Hours=Hours Minutes=Minutes Seconds=Seconds +Weeks=Weeks Today=Today Yesterday=Yesterday Tomorrow=Tomorrow @@ -685,6 +686,7 @@ XMoreLines=%s line(s) hidden PublicUrl=Public URL AddBox=Add box SelectElementAndClickRefresh=Select an element and click Refresh +PrintFile=Print File %s # Week day Monday=Monday Tuesday=Tuesday diff --git a/htdocs/langs/en_US/printgcp.lang b/htdocs/langs/en_US/printgcp.lang new file mode 100644 index 00000000000..ded5fb63d6e --- /dev/null +++ b/htdocs/langs/en_US/printgcp.lang @@ -0,0 +1,25 @@ +# Dolibarr language file - Source file is en_US - printgccp +PRINTGCP=Google Cloud Print +PrintGCPDesc=This driver allow to send documents directly to a printer with Google Cloud Print. +PrintingDriverDescprintgcp=Configuration variables for printing driver Google Cloud Print. +PrintTestDescprintgcp=List of Printers for Google Cloud Print. +PRINTGCP_LOGIN=Google Account Login +PRINTGCP_PASSWORD=Google Account Password +STATE_ONLINE=Online +STATE_UNKNOWN=Unknown +STATE_OFFLINE=Offline +STATE_DORMANT=Offline for quite a while +TYPE_GOOGLE=Google +TYPE_HP=HP Printer +TYPE_DOCS=DOCS +TYPE_DRIVE=Google Drive +TYPE_FEDEX=Fedex +TYPE_ANDROID_CHROME_SNAPSHOT=Android +TYPE_IOS_CHROME_SNAPSHOT=IOS +GCP_Name=Name +GCP_displayName=Display Name +GCP_Id=Printer Id +GCP_OwnerName=Owner Name +GCP_State=Printer State +GCP_connectionStatus=Online State +GCP_Type=Printer Type diff --git a/htdocs/langs/en_US/printing.lang b/htdocs/langs/en_US/printing.lang new file mode 100644 index 00000000000..77c63884636 --- /dev/null +++ b/htdocs/langs/en_US/printing.lang @@ -0,0 +1,10 @@ +# Dolibarr language file - Source file is en_US - printing +PrintingSetup=Setup of Printing System +PrintingDesc=This module adds a Print button to send documents directly to a printer with various module. +ModuleDriverSetup=Setup Module Driver +PrintingDriverDesc=Configuration variables for printing driver. +ListDrivers=List of drivers +PrintTestDesc=List of Printers. +FileWasSentToPrinter=File %s was sent to printer +NoActivePrintingModuleFound=No active module to print document +PleaseSelectaDriverfromList=Please select a driver from list. diff --git a/htdocs/langs/en_US/printipp.lang b/htdocs/langs/en_US/printipp.lang index 835e6827f12..e85d53627c4 100644 --- a/htdocs/langs/en_US/printipp.lang +++ b/htdocs/langs/en_US/printipp.lang @@ -1,6 +1,9 @@ # Dolibarr language file - Source file is en_US - printipp +PRINTIPP=PrintIPP Driver PrintIPPSetup=Setup of Direct Print module -PrintIPPDesc=This module adds a Print button to send documents directly to a printer. It requires a Linux system with CUPS installed. +PrintIPPDesc=This driver allow to send documents directly to a printer. It requires a Linux system with CUPS installed. +PrintingDriverDescprintipp=Configuration variables for printing driver PrintIPP. +PrintTestDescprintipp=List of Printers for driver PrintIPP. PRINTIPP_ENABLED=Show "Direct print" icon in document lists PRINTIPP_HOST=Print server PRINTIPP_PORT=Port @@ -12,3 +15,23 @@ NoDefaultPrinterDefined=No default printer defined DefaultPrinter=Default printer Printer=Printer CupsServer=CUPS Server +IPP_Uri=Printer Uri +IPP_Name=Printer Name +IPP_State=Printer State +IPP_State_reason=State reason +IPP_State_reason1=State reason1 +IPP_BW=BW +IPP_Color=Color +IPP_Device=Device +IPP_Media=Printer media +IPP_Supported=Type of media +STATE_IPP_idle=Idle +STATE_IPP_stopped=Stopped +STATE_IPP_paused=Paused +STATE_IPP_toner-low-report=Low Toner +STATE_IPP_none=None +MEDIA_IPP_stationery=Stationery +MEDIA_IPP_thermal=Thermal +IPP_COLOR_print-black=BW Printer +IPP_COLOR_print-color=Color Printer +IPP_COLOR_=No diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 48f788c96fa..b6244802318 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -736,7 +736,7 @@ if ((! empty($conf->browser->layout) && $conf->browser->layout == 'phone') // If we force to use jmobile, then we reenable javascript if (! empty($conf->dol_use_jmobile)) $conf->use_javascript_ajax=1; // Replace themes bugged with jmobile with eldy -if (! empty($conf->dol_use_jmobile) && in_array($conf->theme,array('bureau2crea','cameleo'))) +if (! empty($conf->dol_use_jmobile) && in_array($conf->theme,array('bureau2crea','cameleo','amarok'))) { $conf->theme='eldy'; $conf->css = "/theme/".$conf->theme."/style.css.php"; diff --git a/htdocs/margin/index.php b/htdocs/margin/index.php index d3897faa551..04a2ba0d544 100644 --- a/htdocs/margin/index.php +++ b/htdocs/margin/index.php @@ -1,5 +1,6 @@ + * Copyright (C) 2014 Marcos García * * 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 @@ -21,5 +22,15 @@ * \brief Page d'index du module margin */ -require 'productMargins.php'; +require '../main.inc.php'; + +if ($user->rights->produit->lire) { + $page = 'productMargins'; +} elseif ($user->rights->societe->lire) { + $page = 'customerMargins'; +} else { + $page = 'agentMargins'; +} + +header('Location: '.dol_buildpath('/margin/'.$page.'.php', 1)); diff --git a/htdocs/margin/lib/margins.lib.php b/htdocs/margin/lib/margins.lib.php index d3ffd9c1bf4..1f904c44f2d 100644 --- a/htdocs/margin/lib/margins.lib.php +++ b/htdocs/margin/lib/margins.lib.php @@ -1,5 +1,6 @@ + * Copyright (C) 2014 Marcos García * * 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 @@ -56,21 +57,25 @@ function marges_admin_prepare_head() */ function marges_prepare_head() { - global $langs, $conf; + global $langs, $conf, $user; $langs->load("marges@marges"); $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT."/margin/productMargins.php"; - $head[$h][1] = $langs->trans("ProductMargins"); - $head[$h][2] = 'productMargins'; - $h++; + if ($user->rights->produit->lire) { + $head[$h][0] = DOL_URL_ROOT."/margin/productMargins.php"; + $head[$h][1] = $langs->trans("ProductMargins"); + $head[$h][2] = 'productMargins'; + $h++; + } - $head[$h][0] = DOL_URL_ROOT."/margin/customerMargins.php"; - $head[$h][1] = $langs->trans("CustomerMargins"); - $head[$h][2] = 'customerMargins'; - $h++; + if ($user->rights->societe->lire) { + $head[$h][0] = DOL_URL_ROOT."/margin/customerMargins.php"; + $head[$h][1] = $langs->trans("CustomerMargins"); + $head[$h][2] = 'customerMargins'; + $h++; + } $head[$h][0] = DOL_URL_ROOT."/margin/agentMargins.php"; $head[$h][1] = $langs->trans("SalesRepresentativeMargins"); diff --git a/htdocs/printing/admin/index.html b/htdocs/printing/admin/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php new file mode 100644 index 00000000000..63784e560f0 --- /dev/null +++ b/htdocs/printing/admin/printing.php @@ -0,0 +1,277 @@ + + * Copyright (C) 2014 Frederic France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/printing/admin/printing.php + * \ingroup printing + * \brief Page to setup printing module + */ + +require '../../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php'; +require_once DOL_DOCUMENT_ROOT.'/printing/lib/printing.lib.php'; + +$langs->load("admin"); +$langs->load("printing"); + +if (! $user->admin) accessforbidden(); + +$action = GETPOST('action','alpha'); +$mode = GETPOST('mode','alpha'); +$value = GETPOST('value','alpha'); +$varname = GETPOST('varname', 'alpha'); +$driver = GETPOST('driver', 'alpha'); + +if (! empty($driver)) $langs->load($driver); + +if (!$mode) $mode='config'; + +/* + * Action + */ + +if (($mode == 'test' || $mode == 'setup') && empty($driver)) +{ + setEventMessage($langs->trans('PleaseSelectaDriverfromList')); + header("Location: ".$_SERVER['PHP_SELF'].'?mode=config'); + exit; +} + +if ($action == 'setconst' && $user->admin) +{ + $error=0; + $db->begin(); + foreach ($_POST['setupdriver'] as $setupconst) { + //print '
'.print_r($setupconst, true).'
'; + $result=dolibarr_set_const($db, $setupconst['varname'],$setupconst['value'],'chaine',0,'',$conf->entity); + if (! $result > 0) $error++; + } + + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans("SetupSaved")); + } + else + { + $db->rollback(); + dol_print_error($db); + } + $action=''; +} + +if ($action == 'setvalue' && $user->admin) +{ + $db->begin(); + + $result=dolibarr_set_const($db, $varname, $value,'chaine',0,'',$conf->entity); + if (! $result > 0) $error++; + + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans("SetupSaved")); + } + else + { + $db->rollback(); + dol_print_error($db); + } + $action = ''; +} + +/* + * View + */ + +$form = new Form($db); + +llxHeader('',$langs->trans("PrintingSetup")); + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans("PrintingSetup"),$linkback,'setup'); + +$head=printingadmin_prepare_head(); + +if ($mode == 'setup' && $user->admin) +{ + print ''; + print ''; + print ''; + + dol_fiche_head($head, $mode, $langs->trans("ModuleDriverSetup"), 0, 'technic'); + + print $langs->trans("PrintingDriverDesc".$driver)."

\n"; + + print ''."\n"; + $var=true; + print ''; + print ''; + print ''; + print "\n"; + + if (! empty($driver)) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $classname = 'printing_'.$driver; + $langs->load($driver); + $printer = new $classname($db); + //print '
'.print_r($printer, true).'
'; + $i=0; + foreach ($printer->conf as $key) { + $var=!$var; + print ''; + print ''.$langs->trans($key['varname']).''; + $i++; + } + } else { + print $langs->trans('PleaseSelectaDriverfromList'); + } + + print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'; + print ''; + print ''; + print ' '.($key['example']!=''?$langs->trans("Example").' : '.$key['example']:''); + print '
'; + if (! empty($driver)) { + print '
'; + } + print ''; + dol_fiche_end(); + +} +if ($mode == 'config' && $user->admin) +{ + dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); + + print $langs->trans("PrintingDesc")."

\n"; + + print ''."\n"; + + $var=true; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + + $object = new PrintingDriver($db); + $result = $object->listDrivers($db, 10); + foreach ($result as $driver) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $classname = 'printing_'.$driver; + $langs->load($driver); + $printer = new $classname($db); + //print '
'.print_r($printer, true).'
'; + $var=!$var; + print ''; + print ''; + print ''; + print ''; + print ''."\n"; + } + + print '
'.$langs->trans("Description").''.$langs->trans("Active").''.$langs->trans("Setup").''.$langs->trans("Test").'
'.img_picto('', $printer->picto).$langs->trans($printer->desc).''; + if (! empty($conf->use_javascript_ajax)) + { + print ajax_constantonoff($printer->active); + } + else + { + if (empty($conf->global->{$printer->conf})) + { + print ''.img_picto($langs->trans("Disabled"),'off').''; + } + else + { + print ''.img_picto($langs->trans("Enabled"),'on').''; + } + } + print ''.img_picto('', 'setup').''.img_picto('', 'setup').'
'; + + dol_fiche_end(); +} + +if ($mode == 'test' && $user->admin) +{ + dol_fiche_head($head, $mode, $langs->trans("PrintingTest"), 0, 'technic'); + + print $langs->trans('PrintTestDesc'.$driver)."

\n"; + + print ''; + if (! empty($driver)) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $classname = 'printing_'.$driver; + $langs->load($driver); + $printer = new $classname($db); + //print '
'.print_r($printer, true).'
'; + print $printer->listAvailablePrinters(); + + } else { + print $langs->trans('PleaseSelectaDriverfromList'); + } + print '
'; + + dol_fiche_end(); +} + +if ($mode == 'userconf' && $user->admin) +{ + dol_fiche_head($head, $mode, $langs->trans("UserConf"), 0, 'technic'); + + print $langs->trans('PrintUserConfDesc'.$driver)."

\n"; + + print ''; + $var=true; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + $sql = 'SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login FROM '.MAIN_DB_PREFIX.'printing as p, '.MAIN_DB_PREFIX.'user as u WHERE p.userid=u.rowid'; + $resql = $db->query($sql); + while ($row=$db->fetch_array($resql)) { + $var=!$var; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + } + print '
'.$langs->trans("User").''.$langs->trans("PrintModule").''.$langs->trans("PrintDriver").''.$langs->trans("Printer").''.$langs->trans("PrinterLocation").''.$langs->trans("PrinterId").''.$langs->trans("NumberOfCopy").''.$langs->trans("Delete").'
'.$row['login'].''.$row['module'].''.$row['driver'].''.$row['printer_name'].''.$row['printer_location'].''.$row['printer_id'].''.$row['copy'].''.img_picto($langs->trans("Delete"), 'delete').'
'; + + dol_fiche_end(); + +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/printipp/index.php b/htdocs/printing/index.php similarity index 61% rename from htdocs/printipp/index.php rename to htdocs/printing/index.php index a130805f16e..e8669f44585 100644 --- a/htdocs/printipp/index.php +++ b/htdocs/printing/index.php @@ -1,5 +1,6 @@ * * 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 @@ -16,20 +17,21 @@ */ /** - * \file htdocs/printipp/index.php - * \ingroup printipp - * \brief Printipp + * \file htdocs/printing/index.php + * \ingroup printing + * \brief Printing */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php'; -llxHeader("",$langs->trans("Printer")); +llxHeader("",$langs->trans("Printing")); -print_fiche_titre($langs->trans("Printer")); +print_fiche_titre($langs->trans("Printing")); -$printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD); -$printer->list_jobs('commande'); +// List Jobs from printing modules +//$printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD); +//$printer->list_jobs('commande'); llxFooter(); diff --git a/htdocs/printing/lib/index.html b/htdocs/printing/lib/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/printipp/lib/printipp.lib.php b/htdocs/printing/lib/printing.lib.php similarity index 55% rename from htdocs/printipp/lib/printipp.lib.php rename to htdocs/printing/lib/printing.lib.php index 64c14609df5..1d09daba0dc 100644 --- a/htdocs/printipp/lib/printipp.lib.php +++ b/htdocs/printing/lib/printing.lib.php @@ -16,44 +16,54 @@ */ /** - * \file htdocs/printipp/lib/printipp.lib.php - * \ingroup printipp - * \brief Library for printipp functions + * \file htdocs/printing/lib/printing.lib.php + * \ingroup printing + * \brief Library for printing functions */ /** - * Define head array for tabs of printipp tools setup pages + * Define head array for tabs of printing tools setup pages * * @return Array of head */ -function printippadmin_prepare_head() +function printingadmin_prepare_head() { global $langs, $conf; $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT."/printipp/admin/printipp.php?mode=config"; - $head[$h][1] = $langs->trans("CupsServer"); + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=config"; + $head[$h][1] = $langs->trans("ListDrivers"); $head[$h][2] = 'config'; $h++; - $head[$h][0] = DOL_URL_ROOT."/printipp/admin/printipp.php?mode=test"; - $head[$h][1] = $langs->trans("Printer"); + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=setup"; + $head[$h][1] = $langs->trans("SetupDriver"); + $head[$h][2] = 'setup'; + $h++; + + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=test"; + $head[$h][1] = $langs->trans("TestDriver"); $head[$h][2] = 'test'; $h++; - $object=new stdClass(); + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=userconf"; + $head[$h][1] = $langs->trans("UserConf"); + $head[$h][2] = 'userconf'; + $h++; + + //$object=new stdClass(); // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab // $this->tabs = array('entity:-tabname); to remove a tab - complete_head_from_modules($conf,$langs,$object,$head,$h,'printippadmin'); + //complete_head_from_modules($conf,$langs,$object,$head,$h,'printingadmin'); - complete_head_from_modules($conf,$langs,$object,$head,$h,'printipp','remove'); + //complete_head_from_modules($conf,$langs,$object,$head,$h,'printing','remove'); return $head; } diff --git a/htdocs/printipp/admin/printipp.php b/htdocs/printipp/admin/printipp.php deleted file mode 100644 index 28ad55453eb..00000000000 --- a/htdocs/printipp/admin/printipp.php +++ /dev/null @@ -1,246 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/printipp/admin/printipp.php - * \ingroup printipp - * \brief Page to setup printipp module - */ - -require '../../main.inc.php'; - -require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php'; -require_once DOL_DOCUMENT_ROOT.'/printipp/lib/printipp.lib.php'; - -$langs->load("admin"); -$langs->load("printipp"); - -if (! $user->admin) accessforbidden(); - -$action = GETPOST('action','alpha'); -$mode = GETPOST('mode','alpha'); -$value = GETPOST('value','alpha'); - -if (!$mode) $mode='config'; - -/* - * Action - */ - -if ($action == 'setvalue' && $user->admin) -{ - $db->begin(); - - if (! $result > 0) $error++; - $result=dolibarr_set_const($db, "PRINTIPP_HOST",GETPOST('PRINTIPP_HOST','alpha'),'chaine',0,'',$conf->entity); - if (! $result > 0) $error++; - $result=dolibarr_set_const($db, "PRINTIPP_PORT",GETPOST('PRINTIPP_PORT','alpha'),'chaine',0,'',$conf->entity); - if (! $result > 0) $error++; - $result=dolibarr_set_const($db, "PRINTIPP_USER",GETPOST('PRINTIPP_USER','alpha'),'chaine',0,'',$conf->entity); - if (! $result > 0) $error++; - $result=dolibarr_set_const($db, "PRINTIPP_PASSWORD",GETPOST('PRINTIPP_PASSWORD','alpha'),'chaine',0,'',$conf->entity); - if (! $result > 0) $error++; - - if (! $error) - { - $db->commit(); - setEventMessage($langs->trans("SetupSaved")); - } - else - { - $db->rollback(); - dol_print_error($db); - } -} - -// Set default model -else if ($action == 'setprinteruri') -{ - if (dolibarr_set_const($db, "PRINTIPP_URI_DEFAULT",$value,'chaine',0,'',$conf->entity)) - { - // La constante qui a ete lue en avant du nouveau set - // on passe donc par une variable pour avoir un affichage coherent - $conf->global->PRINTIPP_URI_DEFAULT = $value; - } -} - - -/* - * View - */ - -$form = new Form($db); - -llxHeader('',$langs->trans("PrintIPPSetup")); - -$linkback=''.$langs->trans("BackToModuleList").''; -print_fiche_titre($langs->trans("PrintIPPSetup"),$linkback,'setup'); - -$head=printippadmin_prepare_head(); - - -if ($mode == 'config' && $user->admin) -{ - print '
'; - print ''; - print ''; - - dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); - - print $langs->trans("PrintIPPDesc")."

\n"; - - print ''; - - $var=true; - print ''; - print ''; - print ''; - print "\n"; - - /* - $var=!$var; - print ''; - */ - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - //$var=true; - //print ''; - //print ''; - //print ''; - //print "\n"; - - print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'; - print $langs->trans("PRINTIPP_ENABLED").''; - - if (! empty($conf->use_javascript_ajax)) - { - print ajax_constantonoff('PRINTIPP_ENABLED'); - } - else - { - if (empty($conf->global->PRINTIPP_ENABLED)) - { - print ''.img_picto($langs->trans("Disabled"),'off').''; - } - else - { - print ''.img_picto($langs->trans("Enabled"),'on').''; - } - } - print '
'; - print $langs->trans("PRINTIPP_HOST").''; - print ''; - print '   '.$langs->trans("Example").': localhost'; - print '
'; - print $langs->trans("PRINTIPP_PORT").''; - print ''; - print '   '.$langs->trans("Example").': 631'; - print '
'; - print $langs->trans("PRINTIPP_USER").''; - print ''; - print '
'; - print $langs->trans("PRINTIPP_PASSWORD").''; - print ''; - print '
'.$langs->trans("OtherParameter").''.$langs->trans("Value").'
'; - - dol_fiche_end(); - - print '
'; - - print ''; -} - -if ($mode == 'test' && $user->admin) -{ - dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); - - print $langs->trans("PrintIPPDesc")."

\n"; - - print ''; - $printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD); - $var=true; - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - print ''; - print "\n"; - - $list = $printer->getlist_available_printers(); - $var = true; - foreach ($list as $value) - { - $var=!$var; - $printer_det = $printer->get_printer_detail($value); - print ""; - print ''; - //print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - // Defaut - print "'; - print "\n"; - } - print '
UriNameStateState_reasonState_reason1BWColorDeviceMediaSupported'.$langs->trans("Select").'
'.$value.'
'.print_r($printer_det,true).'
'.$printer_det->printer_name->_value0.''.$printer_det->printer_state->_value0.''.$printer_det->printer_state_reasons->_value0.''.$printer_det->printer_state_reasons->_value1.''.$printer_det->printer_type->_value2.''.$printer_det->printer_type->_value3.''.$printer_det->device_uri->_value0.''.$printer_det->media_default->_value0.''.$printer_det->media_type_supported->_value1.'"; - if ($conf->global->PRINTIPP_URI_DEFAULT == "$value") - { - print img_picto($langs->trans("Default"),'on'); - } - else - { - print ''.img_picto($langs->trans("Disabled"),'off').''; - } - print '
'; - - if (count($list) == 0) print $langs->trans("NoPrinterFound"); - - dol_fiche_end(); -} - - - -llxFooter(); - -$db->close(); diff --git a/htdocs/product/document.php b/htdocs/product/document.php index 6ca92968e8d..e46dc0384b2 100644 --- a/htdocs/product/document.php +++ b/htdocs/product/document.php @@ -73,16 +73,20 @@ if ($id > 0 || ! empty($ref)) } $modulepart='produit'; + +/* + * Actions + */ + $parameters=array('id'=>$id); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - -/* - * Action envoie fichier - */ - -include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php'; +if (empty($reshook)) +{ + // Action sending file + include_once DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_pre_headers.tpl.php'; +} /* diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 4f382d3b7f8..5adc79f3f65 100755 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -5,7 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010-2012 Juanjo Menent * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2014 Ion Agorria + * Copyright (C) 2014 Ion Agorria * * 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 @@ -81,151 +81,154 @@ $parameters=array('socid'=>$socid, 'id_prod'=>$id); $reshook=$hookmanager->executeHooks('doActions',$parameters,$product,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if ($action == 'remove_pf') +if (empty($reshook)) { - $product = new ProductFournisseur($db); - if ($product->fetch($id) > 0) + if ($action == 'remove_pf') { - if ($rowid) + $product = new ProductFournisseur($db); + if ($product->fetch($id) > 0) { - $result=$product->remove_product_fournisseur_price($rowid); - $action = ''; - setEventMessage($langs->trans("PriceRemoved")); + if ($rowid) + { + $result=$product->remove_product_fournisseur_price($rowid); + $action = ''; + setEventMessage($langs->trans("PriceRemoved")); + } } } -} -if ($action == 'updateprice' && GETPOST('cancel') <> $langs->trans("Cancel")) -{ - $id_fourn=GETPOST("id_fourn"); - if (empty($id_fourn)) $id_fourn=GETPOST("search_id_fourn"); - $ref_fourn=GETPOST("ref_fourn"); - if (empty($ref_fourn)) $ref_fourn=GETPOST("search_ref_fourn"); - $quantity=GETPOST("qty"); - $remise_percent=price2num(GETPOST('remise_percent','alpha')); - $npr = preg_match('/\*/', $_POST['tva_tx']) ? 1 : 0 ; - $tva_tx = str_replace('*','', GETPOST('tva_tx','alpha')); - $tva_tx = price2num($tva_tx); - $price_expression = GETPOST('eid', 'int') == 0 ? 'NULL' : GETPOST('eid', 'int'); //Discard expression if not in expression mode + if ($action == 'updateprice' && GETPOST('cancel') <> $langs->trans("Cancel")) + { + $id_fourn=GETPOST("id_fourn"); + if (empty($id_fourn)) $id_fourn=GETPOST("search_id_fourn"); + $ref_fourn=GETPOST("ref_fourn"); + if (empty($ref_fourn)) $ref_fourn=GETPOST("search_ref_fourn"); + $quantity=GETPOST("qty"); + $remise_percent=price2num(GETPOST('remise_percent','alpha')); + $npr = preg_match('/\*/', $_POST['tva_tx']) ? 1 : 0 ; + $tva_tx = str_replace('*','', GETPOST('tva_tx','alpha')); + $tva_tx = price2num($tva_tx); + $price_expression = GETPOST('eid', 'int') == 0 ? 'NULL' : GETPOST('eid', 'int'); //Discard expression if not in expression mode - if ($tva_tx == '') - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("VATRateForSupplierProduct")), 'errors'); - } - if (empty($quantity)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Qty")), 'errors'); - } - if (empty($ref_fourn)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("RefSupplier")), 'errors'); - } - if ($id_fourn <= 0) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Supplier")), 'errors'); - } - if ($_POST["price"] < 0 || $_POST["price"] == '') - { - if ($price_expression == 'NULL') { //This is not because of using expression instead of numeric price + if ($tva_tx == '') + { $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Price")), 'errors'); + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("VATRateForSupplierProduct")), 'errors'); } - else + if (empty($quantity)) { - $_POST["price"] = 0; + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Qty")), 'errors'); + } + if (empty($ref_fourn)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("RefSupplier")), 'errors'); + } + if ($id_fourn <= 0) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Supplier")), 'errors'); + } + if ($_POST["price"] < 0 || $_POST["price"] == '') + { + if ($price_expression == 'NULL') { //This is not because of using expression instead of numeric price + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Price")), 'errors'); + } + else + { + $_POST["price"] = 0; + } + } + + $product = new ProductFournisseur($db); + $result=$product->fetch($id); + if ($result <= 0) + { + $error++; + setEventMessage($product->error, 'errors'); + } + + if (! $error) + { + $db->begin(); + + if (! $error) + { + $ret=$product->add_fournisseur($user, $id_fourn, $ref_fourn, $quantity); // This insert record with no value for price. Values are update later with update_buyprice + if ($ret == -3) + { + $error++; + + $product->fetch($product->product_id_already_linked); + $productLink = $product->getNomUrl(1,'supplier'); + + setEventMessage($langs->trans("ReferenceSupplierIsAlreadyAssociatedWithAProduct",$productLink), 'errors'); + } + else if ($ret < 0) + { + $error++; + setEventMessage($product->error, 'errors'); + } + } + + if (! $error) + { + $supplier=new Fournisseur($db); + $result=$supplier->fetch($id_fourn); + if (isset($_POST['ref_fourn_price_id'])) + $product->fetch_product_fournisseur_price($_POST['ref_fourn_price_id']); + + $ret=$product->update_buyprice($quantity, $_POST["price"], $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, $npr); + if ($ret < 0) + { + + $error++; + setEventMessage($product->error, 'errors'); + } + else + { + if ($price_expression != 'NULL') { + //Check the expression validity by parsing it + $priceparser = new PriceParser($db); + $price_result = $priceparser->parseProductSupplier($id, $price_expression, $quantity, $tva_tx); + if ($price_result < 0) { //Expression is not valid + $error++; + setEventMessage($priceparser->translatedError(), 'errors'); + } + } + if (! $error && ! empty($conf->dynamicprices->enabled)) { + $ret=$product->setPriceExpression($price_expression); + if ($ret < 0) + { + $error++; + setEventMessage($product->error, 'errors'); + } + } + } + } + + if (! $error) + { + $db->commit(); + $action=''; + } + else + { + $db->rollback(); + } } } - $product = new ProductFournisseur($db); - $result=$product->fetch($id); - if ($result <= 0) + if (GETPOST('cancel') == $langs->trans("Cancel")) { - $error++; - setEventMessage($product->error, 'errors'); + $action = ''; + header("Location: fournisseurs.php?id=".$_GET["id"]); + exit; } - - if (! $error) - { - $db->begin(); - - if (! $error) - { - $ret=$product->add_fournisseur($user, $id_fourn, $ref_fourn, $quantity); // This insert record with no value for price. Values are update later with update_buyprice - if ($ret == -3) - { - $error++; - - $product->fetch($product->product_id_already_linked); - $productLink = $product->getNomUrl(1,'supplier'); - - setEventMessage($langs->trans("ReferenceSupplierIsAlreadyAssociatedWithAProduct",$productLink), 'errors'); - } - else if ($ret < 0) - { - $error++; - setEventMessage($product->error, 'errors'); - } - } - - if (! $error) - { - $supplier=new Fournisseur($db); - $result=$supplier->fetch($id_fourn); - if (isset($_POST['ref_fourn_price_id'])) - $product->fetch_product_fournisseur_price($_POST['ref_fourn_price_id']); - - $ret=$product->update_buyprice($quantity, $_POST["price"], $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, $npr); - if ($ret < 0) - { - $error++; - setEventMessage($product->error, 'errors'); - } - else - { - if ($price_expression != 'NULL') { - //Check the expression validity by parsing it - $priceparser = new PriceParser($db); - $price_result = $priceparser->parseProductSupplier($id, $price_expression, $quantity, $tva_tx); - if ($price_result < 0) { //Expression is not valid - $error++; - setEventMessage($priceparser->translatedError(), 'errors'); - } - } - if (! $error && ! empty($conf->dynamicprices->enabled)) { - $ret=$product->setPriceExpression($price_expression); - if ($ret < 0) - { - $error++; - setEventMessage($product->error, 'errors'); - } - } - } - } - - if (! $error) - { - $db->commit(); - $action=''; - } - else - { - $db->rollback(); - } - } } -if (GETPOST('cancel') == $langs->trans("Cancel")) -{ - $action = ''; - header("Location: fournisseurs.php?id=".$_GET["id"]); - exit; -} - - /* * view @@ -398,7 +401,8 @@ if ($id || $ref) print ''; print ''; - if (! empty($conf->dynamicprices->enabled)) { //Only show price mode and expression selector if module is enabled + if (! empty($conf->dynamicprices->enabled)) //Only show price mode and expression selector if module is enabled + { // Price mode selector print ''.$langs->trans("PriceMode").''; $price_expression = new PriceExpression($db); @@ -456,7 +460,7 @@ if ($id || $ref) print ''; } } - + if (is_object($hookmanager)) { $parameters=array('id_fourn'=>$id_fourn,'prod_id'=>$product->id); @@ -467,7 +471,7 @@ if ($id || $ref) print '
'; print ''; - print '     '; + print '   '; print ''; print '
'; @@ -568,7 +572,7 @@ if ($id || $ref) // Charges ???? if ($conf->global->PRODUCT_CHARGES) - { + { if (! empty($conf->margin->enabled)) { print ''; @@ -576,7 +580,7 @@ if ($id || $ref) print ''; } } - + // Unit price print ''; print price($productfourn->fourn_unitprice); @@ -598,7 +602,7 @@ if ($id || $ref) print ''; } } - + if (is_object($hookmanager)) { $parameters=array('id_pfp'=>$productfourn->product_fourn_price_id,'id_fourn'=>$id_fourn,'prod_id'=>$product->id); diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index bc7478a0dbb..e30a5bfffdc 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -145,12 +145,12 @@ print ''.$langs->trans("Status").''.$project->getLibStatut(4).' // Date start print ''.$langs->trans("DateStart").''; -print dol_print_date($object->date_start,'day'); +print dol_print_date($project->date_start,'day'); print ''; // Date end print ''.$langs->trans("DateEnd").''; -print dol_print_date($object->date_end,'day'); +print dol_print_date($project->date_end,'day'); print ''; print ''; diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php index 33a27796aaf..0863cad9c52 100644 --- a/htdocs/resource/card.php +++ b/htdocs/resource/card.php @@ -62,58 +62,57 @@ $parameters=array('resource_id'=>$id); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - -/******************************************************************* -* ACTIONS -* -* Put here all code to do according to value of "action" parameter -********************************************************************/ - -if ($action == 'update' && ! $_POST["cancel"] && $user->rights->resource->write ) +if (empty($reshook)) { - $error=0; + /******************************************************************* + * ACTIONS + ********************************************************************/ - if (empty($ref)) + if ($action == 'update' && ! $_POST["cancel"] && $user->rights->resource->write ) { - $error++; - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")).'
'; - } + $error=0; - if (! $error) - { - $res = $object->fetch($id); - if ( $res > 0 ) + if (empty($ref)) { - $object->ref = $ref; - $object->description = $description; - $object->fk_code_type_resource = $fk_code_type_resource; + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")), 'errors'); + } - $result=$object->update($user); - if ($result > 0) + if (! $error) + { + $res = $object->fetch($id); + if ( $res > 0 ) { - Header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; + $object->ref = $ref; + $object->description = $description; + $object->fk_code_type_resource = $fk_code_type_resource; + + $result=$object->update($user); + if ($result > 0) + { + Header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + setEventMessage($object->error, 'errors'); + $action='edit'; + } + } else { - setEventMessage('
'.$object->error.'
'); + setEventMessage($object->error,'errors'); $action='edit'; } - } else { - setEventMessage($object->error,'errors'); $action='edit'; } } - else - { - $action='edit'; - } } - /*************************************************** * VIEW * diff --git a/scripts/odt2pdf/odt2pdf.sh b/scripts/odt2pdf/odt2pdf.sh index 9d9bf18a8c7..c7c768a1244 100755 --- a/scripts/odt2pdf/odt2pdf.sh +++ b/scripts/odt2pdf/odt2pdf.sh @@ -1,8 +1,12 @@ #!/bin/bash # @copyright GPL License 2010 - Vikas Mahajan - http://vikasmahajan.wordpress.com # @copyright GPL License 2013 - Florian HEnry - florian.henry@open-concept.pro - # +# Convert an ODT into a PDF using "jodconverter" tool. +# Dolibarr variable MAIN_ODT_AS_PDF must be defined to have this script called after ODT generation. +# Dolibarr variable MAIN_DOL_SCRIPTS_ROOT must be defined to path of script directories (otherwise dolibarr will try to guess). + + #if [ -f "$1.odt" ] # then # soffice --invisible --convert-to pdf:writer_pdf_Export --outdir $2 "$1.odt" diff --git a/test/phpunit/FactureTest.php b/test/phpunit/FactureTest.php index c68014e9606..3248be7104c 100644 --- a/test/phpunit/FactureTest.php +++ b/test/phpunit/FactureTest.php @@ -216,7 +216,7 @@ class FactureTest extends PHPUnit_Framework_TestCase $newlocalobject=new Facture($this->savdb); $newlocalobject->initAsSpecimen(); $this->changeProperties($newlocalobject); - $this->assertEquals($this->objCompare($localobject,$newlocalobject,true,array('newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem','ref','statut','paye','specimen','facnumber','actiontypecode','actionmsg2','actionmsg','mode_reglement','cond_reglement','cond_reglement_doc')), array()); // Actual, Expected + $this->assertEquals($this->objCompare($localobject,$newlocalobject,true,array('newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem','ref','statut','paye','specimen','facnumber','actiontypecode','actionmsg2','actionmsg','mode_reglement','cond_reglement','cond_reglement_doc','situation_cycle_ref','situation_counter','situation_final')), array()); // Actual, Expected return $localobject; } diff --git a/test/phpunit/PricesTest.php b/test/phpunit/PricesTest.php index c01a3701177..9b46f8cc1d6 100755 --- a/test/phpunit/PricesTest.php +++ b/test/phpunit/PricesTest.php @@ -1,20 +1,20 @@ * -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * or see http://www.gnu.org/ -*/ + */ /** * \file test/phpunit/PricesTest.php @@ -215,9 +215,9 @@ class PricesTest extends PHPUnit_Framework_TestCase $newlocalobject=new Facture($this->savdb); $newlocalobject->fetch($invoiceid); - $this->assertEquals(2.48,$newlocalobject->total_ht); - $this->assertEquals(0.24,$newlocalobject->total_tva); - $this->assertEquals(2.72,$newlocalobject->total_ttc); + $this->assertEquals(2.48,$newlocalobject->total_ht, "testUpdatePrice test1"); + $this->assertEquals(0.24,$newlocalobject->total_tva, "testUpdatePrice test2"); + $this->assertEquals(2.72,$newlocalobject->total_ttc, "testUpdatePrice test3"); // Two lines of 1.24 give 2.48 HT and 2.73 TTC with global vat rounding mode @@ -231,7 +231,7 @@ class PricesTest extends PHPUnit_Framework_TestCase $newlocalobject=new Facture($this->savdb); $newlocalobject->fetch($invoiceid); - $this->assertEquals(2.48,$newlocalobject->total_ht); + $this->assertEquals(2.48,$newlocalobject->total_ht, "testUpdatePrice test4"); //$this->assertEquals(0.25,$newlocalobject->total_tva); //$this->assertEquals(2.73,$newlocalobject->total_ttc); }