diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 4f50ce75fe8e4..45ea143114367 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -480,6 +480,13 @@ print ''; print "\n"; +// Allow OnLine Sign +print ''; +print ''.$langs->trans("AllowOnLineSign").''; +print ''; +print ajax_constantonoff('EXPEDITION_ALLOW_ONLINESIGN', array(), null, 0, 0, 0, 2, 0, 1); +print ''; + print ''; print $form->buttonsSaveCancel("Modify", ''); diff --git a/htdocs/core/ajax/onlineSign.php b/htdocs/core/ajax/onlineSign.php index 48e140299e746..5abc559430fd7 100644 --- a/htdocs/core/ajax/onlineSign.php +++ b/htdocs/core/ajax/onlineSign.php @@ -678,6 +678,152 @@ $db->rollback(); } } + } elseif ($mode == 'expedition') { + require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/pdf.lib.php'; + + $object = new Expedition($db); + $object->fetch(0, $ref); + + $upload_dir = $conf->expedition->dir_output."/sending/"; + $upload_dir .= '/'.dol_sanitizeFileName($object->ref).'/'; + + $langs->loadLangs(array("main", "companies")); + + $default_font_size = pdf_getPDFFontSize($langs); // Must be after pdf_getInstance + $default_font = pdf_getPDFFont($langs); // Must be + + $date = dol_print_date(dol_now(), "%Y%m%d%H%M%S"); + $filename = "signatures/" . $date . "_signature.png"; + if (!is_dir($upload_dir . "signatures/")) { + if (!dol_mkdir($upload_dir . "signatures/")) { + $response = "Error mkdir. Failed to create dir " . $upload_dir . "signatures/"; + $error++; + } + } + + if (!$error) { + $return = file_put_contents($upload_dir . $filename, $data); + if ($return == false) { + $error++; + $response = 'Error file_put_content: failed to create signature file.'; + } + } + + if (!$error) { + $last_main_doc_file = $object->last_main_doc; + // Defined modele of doc + if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) { + // It seems document has never been generated, or was generated and then deleted. + // So we try to regenerate it with its default template. + $defaulttemplate = ''; // We force the use an empty string instead of $object->model_pdf to be sure to use a "main" default template and not the last one used. + $object->generateDocument($defaulttemplate, $langs); + } + $last_main_doc_file = $object->last_main_doc; + $directdownloadlink = $object->getLastMainDocLink('expedition'); // url to download the $object->last_main_doc + if (preg_match('/\.pdf/i', $last_main_doc_file)) { + // TODO Use the $last_main_doc_file to defined the $newpdffilename and $sourcefile + $newpdffilename = $upload_dir . $ref . "_signed-" . $date . ".pdf"; + $sourcefile = $upload_dir . $ref . ".pdf"; + + + if (dol_is_file($sourcefile)) { + // We build the new PDF + $pdf = pdf_getInstance(); + if (class_exists('TCPDF')) { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($langs)); + + if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) { + $pdf->SetCompression(false); + } + + //$pdf->Open(); + $pagecount = $pdf->setSourceFile($sourcefile); // original PDF + + $param = array(); + $param['online_sign_name'] = $online_sign_name; + $param['pathtoimage'] = $upload_dir . $filename; + + $s = array(); // Array with size of each page. Example array(w'=>210, 'h'=>297); + for ($i = 1; $i < ($pagecount + 1); $i++) { + try { + $tppl = $pdf->importPage($i); + $s = $pdf->getTemplatesize($tppl); + $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L'); + $pdf->useTemplate($tppl); + + if (getDolGlobalString("SHIPMENT_SIGNATURE_ON_ALL_PAGES")) { + // A signature image file is 720 x 180 (ratio 1/4) but we use only the size into PDF + // TODO Get position of box from PDF template + + $param['xforimgstart'] = 111; + $param['yforimgstart'] = (empty($s['h']) ? 250 : $s['h'] - 60); + $param['wforimg'] = $s['w'] - ($param['xforimgstart'] + 16); + + dolPrintSignatureImage($pdf, $langs, $param); + } + } catch (Exception $e) { + dol_syslog("Error when manipulating some PDF by onlineSign: " . $e->getMessage(), LOG_ERR); + $response = $e->getMessage(); + $error++; + } + } + + if (!getDolGlobalString("SHIPMENT_SIGNATURE_ON_ALL_PAGES")) { + // A signature image file is 720 x 180 (ratio 1/4) but we use only the size into PDF + // TODO Get position of box from PDF template + + $param['xforimgstart'] = 111; + $param['yforimgstart'] = (empty($s['h']) ? 250 : $s['h'] - 60); + $param['wforimg'] = $s['w'] - ($param['xforimgstart'] + 16); + + dolPrintSignatureImage($pdf, $langs, $param); + } + + //$pdf->Close(); + $pdf->Output($newpdffilename, "F"); + + // Index the new file and update the last_main_doc property of object. + $object->indexFile($newpdffilename, 1); + } + if (!$error) { + $response = "success"; + } + } elseif (preg_match('/\.odt/i', $last_main_doc_file)) { + // Adding signature on .ODT not yet supported + // TODO + } else { + // Document format not supported to insert online signature. + // We should just create an image file with the signature. + } + } + + if (!$error) { + $db->begin(); + + $sql = "UPDATE " . MAIN_DB_PREFIX . "expedition"; + $sql .= " SET signed_status = " . ((int) $object::STATUS_SIGNED) ; + $sql .= " WHERE rowid = " . ((int) $object->id); + + dol_syslog(__FILE__, LOG_DEBUG); + $resql = $db->query($sql); + if (!$resql) { + $error++; + } else { + $num = $db->affected_rows($resql); + } + + if (!$error) { + $db->commit(); + $response = "success"; + setEventMessages("ExpeditionSigned", null, 'warnings'); + } else { + $db->rollback(); + } + } } } else { $error++; diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 7f748bf3e0325..c6fa8c698819e 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -2743,6 +2743,14 @@ $linktoelem = $form->showLinkToObjectBlock($object, null, array('shipping')); $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + // Show online signature link + $useonlinesignature = getDolGlobalInt('EXPEDITION_ALLOW_ONLINESIGN'); + + if ($object->statut != Expedition::STATUS_DRAFT && $useonlinesignature) { + print '
'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php'; + print showOnlineSignatureUrl('expedition', $object->ref, $object).'
'; + } print '
'; diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 75ff4241bd11b..68a1ae689fcc3 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -224,6 +224,11 @@ class Expedition extends CommonObject public $multicurrency_total_tva; public $multicurrency_total_ttc; + /** + * @var int + */ + public $signed_status = 0; + /** * Draft status */ @@ -260,6 +265,18 @@ class Expedition extends CommonObject const STATUS_SHIPMENT_IN_PROGRESS = 3; + /** + * No signature + */ + const STATUS_NO_SIGNATURE = 0; + + /** + * Signed status + */ + const STATUS_SIGNED = 1; + + + /** * Constructor * @@ -603,6 +620,7 @@ public function fetch($id, $ref = '', $ref_ext = '', $notused = '') $sql .= ", e.fk_shipping_method, e.tracking_number"; $sql .= ", e.note_private, e.note_public"; $sql .= ', e.fk_incoterms, e.location_incoterms'; + $sql .= ', e.signed_status'; $sql .= ', i.libelle as label_incoterms'; $sql .= ', s.libelle as shipping_method'; $sql .= ", el.fk_source as origin_id, el.sourcetype as origin_type"; @@ -653,7 +671,7 @@ public function fetch($id, $ref = '', $ref_ext = '', $notused = '') $this->origin_id = $obj->origin_id; $this->billed = $obj->billed; $this->fk_project = $obj->fk_project; - + $this->signed_status = $obj->signed_status; $this->trueWeight = $obj->weight; $this->weight_units = $obj->weight_units; diff --git a/htdocs/langs/en_US/commercial.lang b/htdocs/langs/en_US/commercial.lang index 7b0ab3ed30ec3..2ac4a52aff934 100644 --- a/htdocs/langs/en_US/commercial.lang +++ b/htdocs/langs/en_US/commercial.lang @@ -77,14 +77,17 @@ WelcomeOnOnlineSignaturePageProposal=Welcome to the page to accept commercial pr WelcomeOnOnlineSignaturePageContract=Welcome to %s Contract PDF Signing Page WelcomeOnOnlineSignaturePageFichinter=Welcome to %s Intervention PDF Signing Page WelcomeOnOnlineSignaturePageSociete_rib=Welcome to %s SEPA mandate PDF Signing Page +WelcomeOnOnlineSignaturePageExpedition=Welcome to %s Shipment PDF Signing Page ThisScreenAllowsYouToSignDocFromProposal=This screen allow you to accept and sign, or refuse, a quote/commercial proposal ThisScreenAllowsYouToSignDocFromContract=This screen allow you to sign contract on PDF format online. ThisScreenAllowsYouToSignDocFromFichinter=This screen allow you to sign intervention on PDF format online. ThisScreenAllowsYouToSignDocFromSociete_rib=This screen allow you to sign SEPA Mandate on PDF format online. +ThisScreenAllowsYouToSignDocFromExpedition=This screen allow you to sign shipment on PDF format online. ThisIsInformationOnDocumentToSignProposal=This is information on document to accept or refuse ThisIsInformationOnDocumentToSignContract=This is information on contract to sign ThisIsInformationOnDocumentToSignFichinter=This is information on intervention to sign ThisIsInformationOnDocumentToSignSociete_rib=This is information on SEPA Mandate to sign +ThisIsInformationOnDocumentToSignExpedition= This is information on shipment to sign SignatureProposalRef=Signature of quote/commercial proposal %s SignatureContractRef=Signature of contract %s SignatureFichinterRef=Signature of intervention %s diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index 2e8207fe8c0c8..e4dd82ee3a124 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -122,3 +122,5 @@ SignSociete_rib=Sign mandate SignPropal=Accept proposal Signed=signed SignedOnly=Signed only +ExpeditionSigned=Shipment signed +SignExpedition=Sign shipment diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php index d49a9d75ccaae..bbb0c558de647 100644 --- a/htdocs/public/onlinesign/newonlinesign.php +++ b/htdocs/public/onlinesign/newonlinesign.php @@ -54,6 +54,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; // Load translation files $langs->loadLangs(array("main", "other", "dict", "bills", "companies", "errors", "members", "paybox", "stripe", "propal", "commercial")); @@ -122,7 +123,6 @@ $creditor = $mysoc->name; $type = $source; - if (!$action) { if ($source && !$ref) { httponly_accessforbidden($langs->trans('ErrorBadParameters')." - ref missing", 400, 1); @@ -160,6 +160,10 @@ require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; $object = new CompanyBankAccount($db); $result = $object->fetch(0, $ref); +} elseif ($source == 'expedition') { + require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; + $object = new Expedition($db); + $result = $object->fetch(0, $ref); } else { httponly_accessforbidden($langs->trans('ErrorBadParameters')." - Bad value for source. Value not supported.", 400, 1); } @@ -319,6 +323,9 @@ } elseif ($source == 'fichinter') { $text .= '
'.$langs->trans("WelcomeOnOnlineSignaturePageFichinter", $mysoc->name).''."\n"; $text .= ''.$langs->trans("ThisScreenAllowsYouToSignDocFromFichinter", $creditor).'

'."\n"; + } elseif ($source == 'expedition') { + $text .= '
'.$langs->trans("WelcomeOnOnlineSignaturePageExpedition", $mysoc->name).''."\n"; + $text .= ''.$langs->trans("ThisScreenAllowsYouToSignDocFromExpedition", $creditor).'

'."\n"; } else { $text .= '
'.$langs->trans("WelcomeOnOnlineSignaturePage".dol_ucfirst($source), $mysoc->name).''."\n"; $text .= ''.$langs->trans("ThisScreenAllowsYouToSignDocFrom".dol_ucfirst($source), $creditor).'

'."\n"; @@ -335,6 +342,8 @@ print ''.$langs->trans("ThisIsInformationOnDocumentToSignContract").' :'."\n"; } elseif ($source == 'fichinter') { print ''.$langs->trans("ThisIsInformationOnDocumentToSignFichinter").' :'."\n"; +} elseif ($source == 'expedition') { + print ''.$langs->trans("ThisIsInformationOnDocumentToSignExpedition").' :'."\n"; } else { print ''.$langs->trans("ThisIsInformationOnDocumentToSign".dol_ucfirst($source)).' :'."\n"; } @@ -590,6 +599,53 @@ print $langs->trans("DownloadDocument").''; } } +} elseif ($source == 'expedition') { + // Signature on expedition + $found = true; + $langs->load("fichinter"); + + $result = $object->fetch_thirdparty($object->socid); + + // Proposer + print ''.$langs->trans("Proposer"); + print ''; + print img_picto('', 'company', 'class="pictofixedwidth"'); + print ''.$creditor.''; + print ''; + print ''."\n"; + + // Target + print ''.$langs->trans("ThirdParty"); + print ''; + print img_picto('', 'company', 'class="pictofixedwidth"'); + print ''.$object->thirdparty->name.''; + print ''."\n"; + + // Object + $text = ''.$langs->trans("SignatureFichinterRef", $object->ref).''; + print ''.$langs->trans("Designation"); + print ''.$text; + + $last_main_doc_file = $object->last_main_doc; + if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) { + // It seems document has never been generated, or was generated and then deleted. + // So we try to regenerate it with its default template. + $defaulttemplate = ''; // We force the use an empty string instead of $object->model_pdf to be sure to use a "main" default template and not the last one used. + $object->generateDocument($defaulttemplate, $langs); + } + $directdownloadlink = $object->getLastMainDocLink('', 0, 0); + if ($directdownloadlink) { + print '
'; + print img_mime($object->last_main_doc, ''); + if ($message == "signed") { + print $langs->trans("DownloadSignedDocument").''; + } else { + print $langs->trans("DownloadDocument").''; + } + } + print ''; + print ''; + print ''."\n"; } else { $found = true; $langs->load('companies'); @@ -769,6 +825,12 @@ } else { print ''; } + } elseif ($source == 'expedition') { + if ($message == 'signed' || $object->signed_status == Expedition::STATUS_SIGNED) { + print ''.$langs->trans("ExpeditionSigned").''; + } else { + print ''; + } } else { if ($message == 'signed') { print ''.$langs->trans(dol_ucfirst($source)."Signed").'';