diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 590901a937a..2a02522bbcc 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -794,6 +794,8 @@ else if ($action == 'add' && $user->rights->facture->creer) } } + + // Standard or deposit or proforma invoice if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) { @@ -872,126 +874,197 @@ else if ($action == 'add' && $user->rights->facture->creer) 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')) $lines = $srcobject->fetch_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); - - if ($lines[$i]->subprice < 0) + //If deposit invoice + if ($_POST['type'] == 3) { + $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 line"); + $result=$srcobject->fetch($object->origin_id); + if ($result > 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) + $totalamount=0; + $lines = $srcobject->lines; + $num=count($lines); + for ($i=0;$i<$num;$i++) { - $result=$object->insert_discount($discountid); // This include link_to_invoice + $totalamount=+$lines[$i]->subprice; } - else - { - $mesgs[]=$discount->error; - $error++; - break; + + if ($totalamount!=0) { + $amountdeposit=($totalamount*$valuedeposit)/100; } } else { - // Positive line - $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); + $mesgs[]=$srcobject->error; + $error++; + } + + } + + $result = $object->addline( + $id, + $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') + ); + - // 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; + }else { - //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; + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - // 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; - } + $classname = ucfirst($subelement); + $srcobject = new $classname($db); - $result = $object->addline( - $id, - $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 - ); + 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')) $lines = $srcobject->fetch_lines(); - if ($result > 0) + $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); + + if ($lines[$i]->subprice < 0) { - $lineid=$result; + // 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 + { + $mesgs[]=$discount->error; + $error++; + break; + } } else { - $lineid=0; - $error++; - break; - } + // Positive line + $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { - $fk_parent_line = $result; + // 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; + } + + $result = $object->addline( + $id, + $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 + ); + + 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 - { - $mesgs[]=$srcobject->error; - $error++; + // 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 + { + $mesgs[]=$srcobject->error; + $error++; + } } } else @@ -1513,7 +1586,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO // $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf'; // if (is_readable($file)) - // { + // { if ($_POST['sendto']) { // Le destinataire a ete fourni via le champ libre @@ -1658,2055 +1731,2061 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO $mesgs[]='
'.$langs->trans('ErrorCantReadFile',$file).'
'; dol_syslog('Failed to read file: '.$file); } - } - else - { - $langs->load("other"); - $mesgs[]='
'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'
'; - dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); - } - - $action = 'presend'; + } + else + { + $langs->load("other"); + $mesgs[]='
'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'
'; + dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); } - /* - * Generate document - */ - else if ($action == 'builddoc') // En get ou en post + $action = 'presend'; +} + +/* + * Generate document +*/ +else if ($action == 'builddoc') // En get ou en post +{ + $object->fetch($id); + $object->fetch_thirdparty(); + + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model')); + if (GETPOST('fk_bank')) $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->client->default_lang; + if (! empty($newlang)) { - $object->fetch($id); + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + else + { + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); + 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(); - if (GETPOST('model')) $object->setDocModel($user, GETPOST('model')); - if (GETPOST('fk_bank')) $object->fk_bank=GETPOST('fk_bank'); + $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=''; + } +} - // 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->client->default_lang; - if (! empty($newlang)) +if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) +{ + if ($action == 'addcontact') + { + $result = $object->fetch($id); + + if ($result > 0 && $id > 0) { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); } - $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) + + if ($result >= 0) { - dol_print_error($db,$result); + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); exit; } else { - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); - exit; + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $langs->load("errors"); + $mesgs[] = '
'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'
'; + } + else + { + $mesgs[] = '
'.$object->error.'
'; + } } } - // Remove file in doc form - else if ($action == 'remove_file') + // bascule du statut d'un contact + else if ($action == 'swapstatut') { 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=''; - } - } - - 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; - } - else - { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') - { - $langs->load("errors"); - $mesgs[] = '
'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'
'; - } - else - { - $mesgs[] = '
'.$object->error.'
'; - } - } - } - - // bascule du statut d'un contact - 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') - { - $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 ($action == 'update_extras') - { - // Fill array 'array_options' with data from add form - $extralabels=$extrafields->fetch_name_optionals_label('facture'); - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - - // 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)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$object->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; - - } - - - /* - * View - */ - - $form = new Form($db); - $formother=new FormOther($db); - $formfile = new FormFile($db); - $bankaccountstatic=new Account($db); - $now=dol_now(); - - llxHeader('',$langs->trans('Bill'),'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes'); - - - - /********************************************************************* - * - * Mode creation - * - **********************************************************************/ - if ($action == 'create') - { - $facturestatic=new Facture($db); - $extralabels=$extrafields->fetch_name_optionals_label('facture'); - - print_fiche_titre($langs->trans('NewBill')); - - $soc = new Societe($db); - if ($socid>0) $res=$soc->fetch($socid); - - 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 ($element == 'project') - { - $projectid=$originid; - } - else - { - // For compatibility - if ($element == 'order' || $element == 'commande') { - $element = $subelement = 'commande'; - } - if ($element == 'propal') { - $element = 'comm/propal'; $subelement = 'propal'; - } - if ($element == 'contract') { - $element = $subelement = 'contrat'; - } - if ($element == 'shipping') { - $element = $subelement = 'expedition'; - } - - dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - - $classname = ucfirst($subelement); - $objectsrc = new $classname($db); - $objectsrc->fetch($originid); - if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines')) $objectsrc->fetch_lines(); - $objectsrc->fetch_thirdparty(); - - $projectid = (! empty($objectsrc->fk_project)?$objectsrc->fk_project:''); - $ref_client = (! empty($objectsrc->ref_client)?$objectsrc->ref_client:''); - $ref_int = (! empty($objectsrc->ref_int)?$objectsrc->ref_int:''); - - $soc = $objectsrc->thirdparty; - $cond_reglement_id = (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1)); - $mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0)); - $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0)); - $remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0)); - $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; - } + $result=$object->swapContactStatus(GETPOST('ligne')); } else { - $cond_reglement_id = $soc->cond_reglement_id; - $mode_reglement_id = $soc->mode_reglement_id; - $remise_percent = $soc->remise_percent; - $remise_absolue = 0; + dol_print_error($db); + } + } + + // 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 ($action == 'update_extras') +{ + // Fill array 'array_options' with data from add form + $extralabels=$extrafields->fetch_name_optionals_label('facture'); + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + + // 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)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$object->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + +} + + +/* + * View +*/ + +$form = new Form($db); +$formother=new FormOther($db); +$formfile = new FormFile($db); +$bankaccountstatic=new Account($db); +$now=dol_now(); + +llxHeader('',$langs->trans('Bill'),'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes'); + + + +/********************************************************************* + * +* Mode creation +* +**********************************************************************/ +if ($action == 'create') +{ + $facturestatic=new Facture($db); + $extralabels=$extrafields->fetch_name_optionals_label('facture'); + + print_fiche_titre($langs->trans('NewBill')); + + $soc = new Societe($db); + if ($socid>0) $res=$soc->fetch($socid); + + 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 ($element == 'project') + { + $projectid=$originid; + } + else + { + // For compatibility + if ($element == 'order' || $element == 'commande') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + if ($element == 'shipping') { + $element = $subelement = 'expedition'; + } + + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); + + $classname = ucfirst($subelement); + $objectsrc = new $classname($db); + $objectsrc->fetch($originid); + if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines')) $objectsrc->fetch_lines(); + $objectsrc->fetch_thirdparty(); + + $projectid = (! empty($objectsrc->fk_project)?$objectsrc->fk_project:''); + $ref_client = (! empty($objectsrc->ref_client)?$objectsrc->ref_client:''); + $ref_int = (! empty($objectsrc->ref_int)?$objectsrc->ref_int:''); + + $soc = $objectsrc->thirdparty; + $cond_reglement_id = (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1)); + $mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0)); + $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0)); + $remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0)); $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; } - $absolute_discount=$soc->getAvailableDiscounts(); + } + else + { + $cond_reglement_id = $soc->cond_reglement_id; + $mode_reglement_id = $soc->mode_reglement_id; + $remise_percent = $soc->remise_percent; + $remise_absolue = 0; + $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; + } + $absolute_discount=$soc->getAvailableDiscounts(); - if (! empty($conf->use_javascript_ajax)) + if (! empty($conf->use_javascript_ajax)) + { + print ajax_combobox('fac_replacement'); + print ajax_combobox('fac_avoir'); + } + + print '
'; + print ''; + print ''; + if ($soc->id > 0) + print '' ."\n"; + print ''; + print ''; + print ''; + print ''; + print ''; + + print ''; + + // Ref + print ''; + + // Factures predefinies + if (empty($origin) && empty($originid) && $socid>0) + { + $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; + $sql.= ' WHERE r.fk_soc = '.$soc->id; + + $resql=$db->query($sql); + if ($resql) { - print ajax_combobox('fac_replacement'); - print ajax_combobox('fac_avoir'); - } + $num = $db->num_rows($resql); + $i = 0; - print ''; - print ''; - print ''; - if ($soc->id > 0) - print '' ."\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - - print '
'.$langs->trans('Ref').''.$langs->trans('Draft').'
'; - - // Ref - print ''; - - // Factures predefinies - if (empty($origin) && empty($originid) && $socid>0) - { - $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; - $sql.= ' WHERE r.fk_soc = '.$soc->id; - - $resql=$db->query($sql); - if ($resql) + if ($num > 0) { - $num = $db->num_rows($resql); - $i = 0; - - if ($num > 0) + print ''; + $objp = $db->fetch_object($resql); + print ''; + $i++; } - $db->free($resql); + print ''; } - else - { - dol_print_error($db); - } - } - - // Tiers - print ''; - print ''; - if($soc->id > 0) - { - print ''; + $db->free($resql); } else { - print ''; + dol_print_error($db); } - print ''."\n"; + } - // Type de facture - $facids=$facturestatic->list_replacable_invoices($soc->id); - if ($facids < 0) - { - dol_print_error($db,$facturestatic); - exit; - } - $options=""; - foreach ($facids as $facparam) - { - $options.=''; - } + // Tiers + print ''; + print ''; + if($soc->id > 0) + { + print ''; + } + else + { + print ''; + } + print ''."\n"; - $facids=$facturestatic->list_qualified_avoir_invoices($soc->id); - if ($facids < 0) - { - dol_print_error($db,$facturestatic); - exit; - } - $optionsav=""; - $newinvoice_static=new Facture($db); - foreach ($facids as $key => $valarray) - { - $newinvoice_static->id=$key; - $newinvoice_static->ref=$valarray['ref']; - $newinvoice_static->statut=$valarray['status']; - $newinvoice_static->type=$valarray['type']; - $newinvoice_static->paye=$valarray['paye']; + // Type de facture + $facids=$facturestatic->list_replacable_invoices($soc->id); + if ($facids < 0) + { + dol_print_error($db,$facturestatic); + exit; + } + $options=""; + foreach ($facids as $facparam) + { + $options.=''; + } - $optionsav.=''; - } + $facids=$facturestatic->list_qualified_avoir_invoices($soc->id); + if ($facids < 0) + { + dol_print_error($db,$facturestatic); + exit; + } + $optionsav=""; + $newinvoice_static=new Facture($db); + foreach ($facids as $key => $valarray) + { + $newinvoice_static->id=$key; + $newinvoice_static->ref=$valarray['ref']; + $newinvoice_static->statut=$valarray['status']; + $newinvoice_static->type=$valarray['type']; + $newinvoice_static->paye=$valarray['paye']; - print ''; + + if ($socid > 0) + { + // Discounts for third party + print ''; + } + + // Date invoice + print ''; + + // Payment term + print ''; + + // Payment mode + print ''; + + // Project + if (! empty($conf->projet->enabled) && $socid>0) + { + $langs->load('projects'); + print ''; + } + + // Other attributes + $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + print $object->showOptionals($extrafields,'edit'); + } + + // Modele PDF + print ''; + print '"; + + // Public note + print ''; + print ''; + print ''; + + // Private note + if (empty($user->societe_id)) + { + print ''; + print ''; + print ''; + } + + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) + { + // TODO for compatibility + if ($origin == 'contrat') + { + // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva + $objectsrc->remise_absolue=$remise_absolue; + $objectsrc->remise_percent=$remise_percent; + $objectsrc->update_price(1,-1,1); + } + + print "\n"; + print "\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''; + print ''; + + $newclassname=$classname; + if ($newclassname == 'Propal') $newclassname = 'CommercialProposal'; + elseif ($newclassname == 'Commande') $newclassname = 'Order'; + + print ''; + print ''; + print '"; + if ($mysoc->localtax1_assuj=="1") //Localtax1 RE + { + print '"; + } + + if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF + { + print '"; + } + print '"; + } + else + { + // Show deprecated optional form to add product line here + if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) + { + print ''; + print "\n"; } - } - - print "
'.$langs->trans('Ref').''.$langs->trans('Draft').'
'.$langs->trans('CreateFromRepeatableInvoice').''; + print '
'.$langs->trans('CreateFromRepeatableInvoice').''; - print '
'.$langs->trans('Customer').''; - print $soc->getNomUrl(1); - print ''; - print ''; - print $form->select_company('','socid','s.client = 1 OR s.client = 3',1); - print '
'.$langs->trans('Customer').''; + print $soc->getNomUrl(1); + print ''; + print ''; + print $form->select_company('','socid','s.client = 1 OR s.client = 3',1); + print '
'.$langs->trans('Type').''; - print ''."\n"; + $optionsav.=''; + } - // Standard invoice + print ''; - - if ($socid > 0) - { - // Discounts for third party - print ''; - } - - // Date invoice - print ''; - - // Payment term - print ''; - - // Payment mode - print ''; - - // Project - if (! empty($conf->projet->enabled) && $socid>0) - { - $langs->load('projects'); - print ''; - } - - // Other attributes - $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - print $object->showOptionals($extrafields,'edit'); - } - - // Modele PDF - print ''; - print '"; - - // Public note - print ''; - print ''; - print ''; - - // Private note - if (empty($user->societe_id)) - { - print ''; - print ''; - print ''; - } - - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) - { - // TODO for compatibility - if ($origin == 'contrat') - { - // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva - $objectsrc->remise_absolue=$remise_absolue; - $objectsrc->remise_percent=$remise_percent; - $objectsrc->update_price(1,-1,1); - } - - print "\n"; - print "\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''; - print ''; - - $newclassname=$classname; - if ($newclassname == 'Propal') $newclassname = 'CommercialProposal'; - elseif ($newclassname == 'Commande') $newclassname = 'Order'; - - print ''; - print ''; - print '"; - if ($mysoc->localtax1_assuj=="1") //Localtax1 RE - { - print '"; - } - - if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF - { - print '"; - } - print '"; + $text.=''; + $text.=$options; } else { - // Show deprecated optional form to add product line here - if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) - { - print ''."\n"; + } - // Zone de choix des produits predefinis a la creation - print '
'.$langs->trans('Type').''; + print ''."\n"; + + // Standard invoice + print ''."\n"; + + // Proforma + if (! empty($conf->global->FACTURE_USE_PROFORMAT)) + { print ''."\n"; + } - // Proforma - if (! empty($conf->global->FACTURE_USE_PROFORMAT)) - { - print ''."\n"; + if ((empty($origin)) || (($origin=='propal') && (!empty($originid)))) + { + // Deposit + print ''."\n"; + } - if (empty($origin)) + if ($socid > 0) + { + // Replacement + print ''."\n"; - } - - if ($socid > 0) - { - // Replacement - print ''."\n"; - } - - if (empty($origin) && $socid > 0) - { - // Credit note - print ''."\n"; - } - - print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1); + print $desc; + print '
'; - print ''; + print ''; print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1); + $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1); print $desc; print '
'; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1); - print $desc; - print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1); + print ''; + if (($origin=='propal') ) { + print ''; + print '
'.$desc.''.$langs->trans('Value').':'; } + print '
'; + print '
'; + print ''; + print ''; + $text=$langs->trans("InvoiceReplacementAsk").' '; + $text.=''; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $text=$langs->trans("InvoiceReplacementAsk").' '; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $text=$langs->transnoentities("InvoiceAvoirAsk").' '; - // $text.=''; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); - print $desc; - print '
'; - print '
'.$langs->trans('Discounts').''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",''.$soc->remise_client.''); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - print ' ('.$langs->trans("EditRelativeDiscount").')'; - print '. '; - print '
'; - if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",''.price($absolute_discount).'',$langs->trans("Currency".$conf->currency)); - else print $langs->trans("CompanyHasNoAbsoluteDiscount"); - print ' ('.$langs->trans("EditGlobalDiscounts").')'; - print '.'; - print '
'.$langs->trans('Date').''; - $form->select_date($dateinvoice,'','','','',"add",1,1); - print '
'.$langs->trans('PaymentConditionsShort').''; - $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id'); - print '
'.$langs->trans('PaymentMode').''; - $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id'); - print '
'.$langs->trans('Project').''; - select_projects($soc->id, $projectid, 'projectid'); - print '
'.$langs->trans('Model').''; - include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php'; - $liste=ModelePDFFactures::liste_modeles($db); - print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF); - print "
'.$langs->trans('NotePublic').''; - $note_public=''; - if (is_object($objectsrc)) // Take value from source object - { - $note_public=$objectsrc->note_public; - } - $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); - print $doleditor->Create(1); - - //print '
'.$langs->trans('NotePrivate').''; - $note_private=''; - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) // Take value from source object - { - $note_private=$objectsrc->note_private; - } - $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); - print $doleditor->Create(1); - //print '
'.$langs->trans($newclassname).''.$objectsrc->getNomUrl(1).'
'.$langs->trans('TotalHT').''.price($objectsrc->total_ht).'
'.$langs->trans('TotalVAT').''.price($objectsrc->total_tva)."
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($objectsrc->total_localtax1)."
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($objectsrc->total_localtax2)."
'.$langs->trans('TotalTTC').''.price($objectsrc->total_ttc)."
'; + $text.=''; + } + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); + print $desc; + print '
'; + if (empty($origin) && $socid > 0) + { + // Credit note + print ''."\n"; + } + + print '
'; + print ''; + print ''; + $text=$langs->transnoentities("InvoiceAvoirAsk").' '; + // $text.=''; + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); + print $desc; + print '
'; + print '
'.$langs->trans('Discounts').''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",''.$soc->remise_client.''); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + print ' ('.$langs->trans("EditRelativeDiscount").')'; + print '. '; + print '
'; + if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",''.price($absolute_discount).'',$langs->trans("Currency".$conf->currency)); + else print $langs->trans("CompanyHasNoAbsoluteDiscount"); + print ' ('.$langs->trans("EditGlobalDiscounts").')'; + print '.'; + print '
'.$langs->trans('Date').''; + $form->select_date($dateinvoice,'','','','',"add",1,1); + print '
'.$langs->trans('PaymentConditionsShort').''; + $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id'); + print '
'.$langs->trans('PaymentMode').''; + $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id'); + print '
'.$langs->trans('Project').''; + select_projects($soc->id, $projectid, 'projectid'); + print '
'.$langs->trans('Model').''; + include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php'; + $liste=ModelePDFFactures::liste_modeles($db); + print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF); + print "
'.$langs->trans('NotePublic').''; + $note_public=''; + if (is_object($objectsrc)) // Take value from source object + { + $note_public=$objectsrc->note_public; + } + $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + + //print '
'.$langs->trans('NotePrivate').''; + $note_private=''; + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) // Take value from source object + { + $note_private=$objectsrc->note_private; + } + $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + //print '
'.$langs->trans($newclassname).''.$objectsrc->getNomUrl(1).'
'.$langs->trans('TotalHT').''.price($objectsrc->total_ht).'
'.$langs->trans('TotalVAT').''.price($objectsrc->total_tva)."
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($objectsrc->total_localtax1)."
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($objectsrc->total_localtax2)."
'.$langs->trans('TotalTTC').''.price($objectsrc->total_ttc)."
'; + + // Zone de choix des produits predefinis a la creation + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->service->enabled)) + { + print ''; + } + print ''; + for ($i = 1 ; $i <= $NBLINES ; $i++) + { print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + // Si le module service est actif, on propose des dates de debut et fin a la ligne if (! empty($conf->service->enabled)) { - print ''; - } - print ''; - for ($i = 1 ; $i <= $NBLINES ; $i++) - { - print ''; - print ''; - print ''; - print ''; - print ''; - // Si le module service est actif, on propose des dates de debut et fin a la ligne - if (! empty($conf->service->enabled)) - { - print ''; - } - print "\n"; } - - print '
'.$langs->trans('ProductsAndServices').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'     '.$langs->trans('ServiceLimitedDuration').'
'.$langs->trans('ProductsAndServices').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'     '; + // multiprix + if (! empty($conf->global->PRODUIT_MULTIPRICES)) + $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level); + else + $form->select_produits('','idprod'.$i,'',$conf->product->limit_size); + print '% '.$langs->trans('ServiceLimitedDuration').'
'; - // multiprix - if (! empty($conf->global->PRODUIT_MULTIPRICES)) - $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level); - else - $form->select_produits('','idprod'.$i,'',$conf->product->limit_size); + print ''; + print ''; + print ''; + print '
'; + print $langs->trans('From').' '; + print ''; + print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add"); + print '
'; + print $langs->trans('to').' '; + print ''; + print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add"); + print '
'; print '
% '; - print ''; - print ''; - print '
'; - print $langs->trans('From').' '; - print ''; - print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add"); - print '
'; - print $langs->trans('to').' '; - print ''; - print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add"); - print '
'; - print '
'; - print '
\n"; - - // Button "Create Draft" - print '
'; - - print "
\n"; - - // Show origin lines - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) - { - print '
'; - - $title=$langs->trans('ProductsAndServices'); - print_titre($title); - - print ''; - - $objectsrc->printOriginLinesList(); print '
'; + print ''; + } + } + + print "\n"; + + // Button "Create Draft" + print '
'; + + print "\n"; + + // Show origin lines + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) + { + print '
'; + + $title=$langs->trans('ProductsAndServices'); + print_titre($title); + + print ''; + + $objectsrc->printOriginLinesList(); + + print '
'; + } + +} +else if ($id > 0 || ! empty($ref)) +{ + /* + * Show object in view mode + */ + + $result=$object->fetch($id,$ref); + + // fetch optionals attributes and labels + $extralabels=$extrafields->fetch_name_optionals_label('facture'); + + if ($result > 0) + { + if ($user->societe_id>0 && $user->societe_id!=$object->socid) accessforbidden('',0); + + $result=$object->fetch_thirdparty(); + + $soc = new Societe($db); + $soc->fetch($object->socid); + $selleruserevenustamp=$mysoc->useRevenueStamp(); + + $totalpaye = $object->getSommePaiement(); + $totalcreditnotes = $object->getSumCreditNotesUsed(); + $totaldeposits = $object->getSumDepositsUsed(); + //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp; + + // We can also use bcadd to avoid pb with floating points + // For example print 239.2 - 229.3 - 9.9; does not return 0. + //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); + //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); + $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT'); + + if ($object->paye) $resteapayer=0; + $resteapayeraffiche=$resteapayer; + + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) + { + $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + } + else + { + $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; + $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; } - } - else if ($id > 0 || ! empty($ref)) - { - /* - * Show object in view mode - */ + $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount); + $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote); + $absolute_discount=price2num($absolute_discount,'MT'); + $absolute_creditnote=price2num($absolute_creditnote,'MT'); - $result=$object->fetch($id,$ref); - - // fetch optionals attributes and labels - $extralabels=$extrafields->fetch_name_optionals_label('facture'); - - if ($result > 0) + $author = new User($db); + if ($object->user_author) { - if ($user->societe_id>0 && $user->societe_id!=$object->socid) accessforbidden('',0); + $author->fetch($object->user_author); + } - $result=$object->fetch_thirdparty(); + $objectidnext=$object->getIdReplacingInvoice(); - $soc = new Societe($db); - $soc->fetch($object->socid); - $selleruserevenustamp=$mysoc->useRevenueStamp(); - $totalpaye = $object->getSommePaiement(); - $totalcreditnotes = $object->getSumCreditNotesUsed(); - $totaldeposits = $object->getSumDepositsUsed(); - //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp; + $head = facture_prepare_head($object); - // We can also use bcadd to avoid pb with floating points - // For example print 239.2 - 229.3 - 9.9; does not return 0. - //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); - //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); - $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT'); + dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill'); - if ($object->paye) $resteapayer=0; - $resteapayeraffiche=$resteapayer; + $formconfirm=''; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) + // Confirmation de la conversion de l'avoir en reduc + if ($action == 'converttoreduc') + { + $text=$langs->trans('ConfirmConvertToReduc'); + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2); + } + + // Confirmation to delete invoice + if ($action == 'delete') + { + $text=$langs->trans('ConfirmDeleteBill',$object->ref); + $formquestion=array(); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $qualified_for_stock_change=$object->hasProductsOrServices(2); } else { - $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; - $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; + $qualified_for_stock_change=$object->hasProductsOrServices(1); } - $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount); - $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote); - $absolute_discount=price2num($absolute_discount,'MT'); - $absolute_creditnote=price2num($absolute_creditnote,'MT'); - - $author = new User($db); - if ($object->user_author) + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change && $object->statut>=1) { - $author->fetch($object->user_author); + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1,0,0,$langs->trans("NoStockAction")))); + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete',$formquestion,"yes",1); + }else { + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','','',1); } + } - $objectidnext=$object->getIdReplacingInvoice(); - - - $head = facture_prepare_head($object); - - dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill'); - - $formconfirm=''; - - // Confirmation de la conversion de l'avoir en reduc - if ($action == 'converttoreduc') + // Confirmation de la validation + if ($action == 'valid') + { + // on verifie si l'objet est en numerotation provisoire + $objectref = substr($object->ref, 1, 4); + if ($objectref == 'PROV') { - $text=$langs->trans('ConfirmConvertToReduc'); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2); + $savdate=$object->date; + if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) + { + $object->date=dol_now(); + $object->date_lim_reglement=$object->calculate_date_lim_reglement(); + } + $numref = $object->getNextNumRef($soc); + //$object->date=$savdate; } - - // Confirmation to delete invoice - if ($action == 'delete') + else { - $text=$langs->trans('ConfirmDeleteBill',$object->ref); - $formquestion=array(); - - $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); - } - - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change && $object->statut>=1) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1,0,0,$langs->trans("NoStockAction")))); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete',$formquestion,"yes",1); - }else { - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','','',1); - } + $numref = $object->ref; } - // Confirmation de la validation - if ($action == 'valid') + $text=$langs->trans('ConfirmValidateBill',$numref); + if (! empty($conf->notification->enabled)) { - // on verifie si l'objet est en numerotation provisoire - $objectref = substr($object->ref, 1, 4); - if ($objectref == 'PROV') - { - $savdate=$object->date; - if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) - { - $object->date=dol_now(); - $object->date_lim_reglement=$object->calculate_date_lim_reglement(); - } - $numref = $object->getNextNumRef($soc); - //$object->date=$savdate; - } - else - { - $numref = $object->ref; - } - - $text=$langs->trans('ConfirmValidateBill',$numref); - if (! empty($conf->notification->enabled)) - { - require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; - $notify=new Notify($db); - $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid); - } - $formquestion=array(); - - $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); - } - - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease"); - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); - } - if ($object->type != 2 && $object->total_ttc < 0) // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on - { - $text.='
'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive"); - } - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2)); + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid); } + $formquestion=array(); - // Confirm back to draft status - if ($action == 'modif') + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $text=$langs->trans('ConfirmUnvalidateBill',$object->ref); - $formquestion=array(); - - $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); - } - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); - } - - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1); + $qualified_for_stock_change=$object->hasProductsOrServices(2); } - - // Confirmation du classement paye - if ($action == 'paid' && $resteapayer <= 0) + else { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1); + $qualified_for_stock_change=$object->hasProductsOrServices(1); } - if ($action == 'paid' && $resteapayer > 0) + + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); + } + if ($object->type != 2 && $object->total_ttc < 0) // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on + { + $text.='
'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive"); + } + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2)); + } + + // Confirm back to draft status + if ($action == 'modif') + { + $text=$langs->trans('ConfirmUnvalidateBill',$object->ref); + $formquestion=array(); + + $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); + } + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); + } + + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1); + } + + // Confirmation du classement paye + if ($action == 'paid' && $resteapayer <= 0) + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1); + } + if ($action == 'paid' && $resteapayer > 0) + { + // Code + $i=0; + $close[$i]['code']='discount_vat';$i++; + $close[$i]['code']='badcustomer';$i++; + // Help + $i=0; + $close[$i]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++; + $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++; + // Texte + $i=0; + $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; + $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; + // arrayreasons[code]=reason + foreach($close as $key => $val) + { + $arrayreasons[$close[$key]['code']]=$close[$key]['reason']; + } + + // Cree un tableau formulaire + $formquestion=array( + 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), + array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), + array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes"); + } + + // Confirmation du classement abandonne + if ($action == 'canceled') + { + // S'il y a une facture de remplacement pas encore validee (etat brouillon), + // on ne permet pas de classer abandonner la facture. + if ($objectidnext) + { + $facturereplacement=new Facture($db); + $facturereplacement->fetch($objectidnext); + $statusreplacement=$facturereplacement->statut; + } + if ($objectidnext && $statusreplacement == 0) + { + print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; + } + else { // Code - $i=0; - $close[$i]['code']='discount_vat';$i++; - $close[$i]['code']='badcustomer';$i++; + $close[1]['code']='badcustomer'; + $close[2]['code']='abandon'; // Help - $i=0; - $close[$i]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++; - $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++; + $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); + $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc"); // Texte - $i=0; - $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; - $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; - // arrayreasons[code]=reason - foreach($close as $key => $val) - { - $arrayreasons[$close[$key]['code']]=$close[$key]['reason']; - } + $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1); + $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1); + // arrayreasons + $arrayreasons[$close[1]['code']]=$close[1]['reason']; + $arrayreasons[$close[2]['code']]=$close[2]['reason']; // Cree un tableau formulaire $formquestion=array( - 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), + 'text' => $langs->trans("ConfirmCancelBillQuestion"), array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') ); - // Paiement incomplet. On demande si motif = escompte ou autre - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes"); - } - // Confirmation du classement abandonne - if ($action == 'canceled') + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes"); + } + } + + // Confirmation de la suppression d'une ligne produit + if ($action == 'ask_deleteline') + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1); + } + + // Clone confirmation + if ($action == 'clone') + { + // Create an array for form + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1) + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1); + } + + if (! $formconfirm) + { + $parameters=array('lineid'=>$lineid); + $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + } + + // Print form confirm + print $formconfirm; + + + // Invoice content + + print ''; + + $linkback = ''.$langs->trans("BackToList").''; + + // Ref + print ''; + print ''; + + // Ref customer + print ''; + print ''; + + // Third party + print ''; + + // Type + print ''; + + // Relative and absolute discounts + $addrelativediscount=''.$langs->trans("EditRelativeDiscounts").''; + $addabsolutediscount=''.$langs->trans("EditGlobalDiscounts").''; + $addcreditnote=''.$langs->trans("AddCreditNote").''; + + print ''; + + // Conditions de reglement + print ''; - - // Conditions de reglement - print ''; + } + else + { + print ' '; + } + print ''; - // Date payment term - print ''; + } + else + { + print ' '; + } + print ''; - // Payment mode + // Payment mode + print ''; + + // Amount + print ''; + print ''; + print ''; + print ''; + + // Amount Local Taxes + if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE) + { + print ''; + print ''; + } + if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF) + { + print ''; + print ''; + } + + // Revenue stamp + if ($selleruserevenustamp) // Test company use revenue stamp + { print ''; + } - // Amount - print ''; - print ''; - print ''; + // Total with tax + print ''; + + // Statut + print ''; + print ''; + + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load('projects'); + print ''; + print ''; print ''; + } - // Amount Local Taxes - if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE) + // Other attributes + $res=$object->fetch_optionals($object->id,$extralabels); + $parameters=array('colspan' => ' colspan="2"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + + if ($action == 'edit_extras') { - print ''; - print ''; - } - if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF) - { - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; } - // Revenue stamp - if ($selleruserevenustamp) // Test company use revenue stamp + foreach($extrafields->attribute_label as $key=>$label) { - print ''; - } - - // Total with tax - print ''; - - // Statut - print ''; - print ''; - - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load('projects'); - print ''; - print ''; - print ''; - } - - // Other attributes - $res=$object->fetch_optionals($object->id,$extralabels); - $parameters=array('colspan' => ' colspan="2"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - - if ($action == 'edit_extras') - { - print ''; - print ''; - print ''; - print ''; - } - - foreach($extrafields->attribute_label as $key=>$label) - { - $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); - if ($extrafields->attribute_type[$key] == 'separate') + print 'attribute_required[$key])) print ' class="fieldrequired"'; + print '>'.$label.'attribute_required[$key])) print ' class="fieldrequired"'; - print '>'.$label.''."\n"; - } - } - - if(count($extrafields->attribute_label) > 0) { if ($action == 'edit_extras' && $user->rights->facture->creer) { - print ''; - + print $extrafields->showInputField($key,$value); } - else { - if ($object->statut == 0 && $user->rights->facture->creer) - { - print ''; - } - } - } - } - - print '
'.$langs->trans('Ref').''; + $morehtmlref=''; + $discount=new DiscountAbsolute($db); + $result=$discount->fetch(0,$object->id); + if ($result > 0) + { + $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')'; + } + if ($result < 0) + { + dol_print_error('',$discount->error); + } + print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref); + print '
'; + print ''; + if ($action != 'refclient' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('RefCustomer'); + print ''.img_edit($langs->trans('Modify')).'
'; + print '
'; + if ($user->rights->facture->creer && $action == 'refclient') + { + print '
'; + print ''; + print ''; + print ''; + print ' '; + print '
'; + } + else + { + print $object->ref_client; + } + print '
'; + print ''; + print ''; + print ''; + print '
'.$langs->trans('Company').''; + if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer) + print 'id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'
'; + print '
'; + if ($action == 'editthirdparty') + { + $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid'); + } + else + { + print '  '.$soc->getNomUrl(1,'compta'); + print '   ('.$langs->trans('OtherBills').')'; + } + print '
'.$langs->trans('Type').''; + print $object->getLibType(); + if ($object->type == 1) + { + $facreplaced=new Facture($db); + $facreplaced->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; + } + if ($object->type == 2) + { + $facusing=new Facture($db); + $facusing->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; + } + + $facidavoir=$object->getListIdAvoirFromInvoice(); + if (count($facidavoir) > 0) + { + print ' ('.$langs->transnoentities("InvoiceHasAvoir"); + $i=0; + foreach($facidavoir as $id) { - // S'il y a une facture de remplacement pas encore validee (etat brouillon), - // on ne permet pas de classer abandonner la facture. - if ($objectidnext) + if ($i==0) print ' '; + else print ','; + $facavoir=new Facture($db); + $facavoir->fetch($id); + print $facavoir->getNomUrl(1); + } + print ')'; + } + if ($objectidnext > 0) + { + $facthatreplace=new Facture($db); + $facthatreplace->fetch($objectidnext); + print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; + } + print '
'.$langs->trans('Discounts'); + print ''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + //print ' ('.$addrelativediscount.')'; + + if ($absolute_discount > 0) + { + print '. '; + if ($object->statut > 0 || $object->type == 2 || $object->type == 3) + { + if ($object->statut == 0) { - $facturereplacement=new Facture($db); - $facturereplacement->fetch($objectidnext); - $statusreplacement=$facturereplacement->statut; - } - if ($objectidnext && $statusreplacement == 0) - { - print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; + print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + print '. '; } else { - // Code - $close[1]['code']='badcustomer'; - $close[2]['code']='abandon'; - // Help - $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); - $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc"); - // Texte - $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1); - $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1); - // arrayreasons - $arrayreasons[$close[1]['code']]=$close[1]['reason']; - $arrayreasons[$close[2]['code']]=$close[2]['reason']; - - // Cree un tableau formulaire - $formquestion=array( - 'text' => $langs->trans("ConfirmCancelBillQuestion"), - array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), - array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') - ); - - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes"); - } - } - - // Confirmation de la suppression d'une ligne produit - if ($action == 'ask_deleteline') - { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1); - } - - // Clone confirmation - if ($action == 'clone') - { - // Create an array for form - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1) - ); - // Paiement incomplet. On demande si motif = escompte ou autre - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1); - } - - if (! $formconfirm) - { - $parameters=array('lineid'=>$lineid); - $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - } - - // Print form confirm - print $formconfirm; - - - // Invoice content - - print ''; - - $linkback = ''.$langs->trans("BackToList").''; - - // Ref - print ''; - print ''; - - // Ref customer - print ''; - print ''; - - // Third party - print ''; - - // Type - print ''; - - // Relative and absolute discounts - $addrelativediscount=''.$langs->trans("EditRelativeDiscounts").''; - $addabsolutediscount=''.$langs->trans("EditGlobalDiscounts").''; - $addcreditnote=''.$langs->trans("AddCreditNote").''; - - print ''; - - // Date invoice - print ''; + + // Date invoice + print ''; + } + else + { + print dol_print_date($object->date,'daytext'); + } + print ''; - /* - * List of payments - */ + /* + * List of payments + */ - $sign=1; - if ($object->type == 2) $sign=-1; + $sign=1; + if ($object->type == 2) $sign=-1; - $nbrows=8; $nbcols=2; - if (! empty($conf->projet->enabled)) $nbrows++; - if (! empty($conf->banque->enabled)) $nbcols++; - if($mysoc->localtax1_assuj=="1") $nbrows++; - if($mysoc->localtax2_assuj=="1") $nbrows++; - if ($selleruserevenustamp) $nbrows++; + $nbrows=8; $nbcols=2; + if (! empty($conf->projet->enabled)) $nbrows++; + if (! empty($conf->banque->enabled)) $nbcols++; + if($mysoc->localtax1_assuj=="1") $nbrows++; + if($mysoc->localtax2_assuj=="1") $nbrows++; + if ($selleruserevenustamp) $nbrows++; - print ''; - // Margin Infos - if (! empty($conf->margin->enabled)) + // Remainder to pay + print ''; + print ''; + print ''; + } + else // Credit note + { + // Total already paid back + print ''; + + // Billed + print ''; + + // Remainder to pay back + print ''; + print ''; + print ''; + + // Sold credit note + //print ''; + //print ''; + } + + print '
'.$langs->trans('Ref').''; - $morehtmlref=''; - $discount=new DiscountAbsolute($db); - $result=$discount->fetch(0,$object->id); - if ($result > 0) - { - $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')'; - } - if ($result < 0) - { - dol_print_error('',$discount->error); - } - print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref); - print '
'; - print ''; - if ($action != 'refclient' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('RefCustomer'); - print ''.img_edit($langs->trans('Modify')).'
'; - print '
'; - if ($user->rights->facture->creer && $action == 'refclient') - { - print '
'; - print ''; - print ''; - print ''; - print ' '; - print '
'; - } - else - { - print $object->ref_client; - } - print '
'; - print ''; - print ''; - print ''; - print '
'.$langs->trans('Company').''; - if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer) - print 'id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'
'; - print '
'; - if ($action == 'editthirdparty') - { - $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid'); - } - else - { - print '  '.$soc->getNomUrl(1,'compta'); - print '   ('.$langs->trans('OtherBills').')'; - } - print '
'.$langs->trans('Type').''; - print $object->getLibType(); - if ($object->type == 1) - { - $facreplaced=new Facture($db); - $facreplaced->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; - } - if ($object->type == 2) - { - $facusing=new Facture($db); - $facusing->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; - } - - $facidavoir=$object->getListIdAvoirFromInvoice(); - if (count($facidavoir) > 0) - { - print ' ('.$langs->transnoentities("InvoiceHasAvoir"); - $i=0; - foreach($facidavoir as $id) - { - if ($i==0) print ' '; - else print ','; - $facavoir=new Facture($db); - $facavoir->fetch($id); - print $facavoir->getNomUrl(1); - } - print ')'; - } - if ($objectidnext > 0) - { - $facthatreplace=new Facture($db); - $facthatreplace->fetch($objectidnext); - print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; - } - print '
'.$langs->trans('Discounts'); - print ''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - //print ' ('.$addrelativediscount.')'; - - if ($absolute_discount > 0) - { - print '. '; - if ($object->statut > 0 || $object->type == 2 || $object->type == 3) - { - if ($object->statut == 0) + if ($object->statut < 1 || $object->type == 2 || $object->type == 3) { - print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '. '; + $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + print '
'.$text.'.
'; } else { - if ($object->statut < 1 || $object->type == 2 || $object->type == 3) - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '
'.$text.'.
'; - } - else - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - $text2=$langs->trans("AbsoluteDiscountUse"); - print $form->textwithpicto($text,$text2); - } + $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + $text2=$langs->trans("AbsoluteDiscountUse"); + print $form->textwithpicto($text,$text2); } } - else - { - // Remise dispo de type remise fixe (not credit note) - print '
'; - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')'); - } } else { - if ($absolute_creditnote > 0) // If not, link will be added later - { - if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; - else print '. '; - } - else print '. '; + // Remise dispo de type remise fixe (not credit note) + print '
'; + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')'); } - if ($absolute_creditnote > 0) + } + else + { + if ($absolute_creditnote > 0) // If not, link will be added later { - // If validated, we show link "add credit note to payment" - if ($object->statut != 1 || $object->type == 2 || $object->type == 3) - { - if ($object->statut == 0 && $object->type != 3) - { - $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)); - print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse")); - } - else - { - print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.'; - } - } - else - { - // Remise dispo de type avoir - if (! $absolute_discount) print '
'; - //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher - } - } - if (! $absolute_discount && ! $absolute_creditnote) - { - print $langs->trans("CompanyHasNoAbsoluteDiscount"); if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; else print '. '; } - /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3) - { - if (! $absolute_discount && ! $absolute_creditnote) print '
'; - //print '   -   '; - print $addabsolutediscount; - //print '   -   '.$addcreditnote; // We disbale link to credit note - }*/ - print '
'; - print ''; - if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('Date'); - print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; - print '
'; - - if ($object->type != 2) + else print '. '; + } + if ($absolute_creditnote > 0) + { + // If validated, we show link "add credit note to payment" + if ($object->statut != 1 || $object->type == 2 || $object->type == 3) { - if ($action == 'editinvoicedate') + if ($object->statut == 0 && $object->type != 3) { - $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate'); + $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)); + print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse")); } else { - print dol_print_date($object->date,'daytext'); + print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.'; } } else + { + // Remise dispo de type avoir + if (! $absolute_discount) print '
'; + //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher + } + } + if (! $absolute_discount && ! $absolute_creditnote) + { + print $langs->trans("CompanyHasNoAbsoluteDiscount"); + if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; + else print '. '; + } + /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3) + { + if (! $absolute_discount && ! $absolute_creditnote) print '
'; + //print '   -   '; + print $addabsolutediscount; + //print '   -   '.$addcreditnote; // We disbale link to credit note + }*/ + print '
'; + print ''; + if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('Date'); + print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; + print '
'; + + if ($object->type != 2) + { + if ($action == 'editinvoicedate') + { + $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate'); + } + else { print dol_print_date($object->date,'daytext'); } - print ''; + print ''; - print ''; + print '
'; - // List of payments already done - print ''; - print ''; - print ''; - if (! empty($conf->banque->enabled)) print ''; - print ''; - print ''; - print ''; + // List of payments already done + print ''; + print ''; + print ''; + if (! empty($conf->banque->enabled)) print ''; + print ''; + print ''; + print ''; - $var=true; + $var=true; - // Payments already done (from payment on this invoice) - $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,'; - $sql.= ' c.code as payment_code, c.libelle as payment_label,'; - $sql.= ' pf.amount,'; - $sql.= ' ba.rowid as baid, ba.ref, ba.label'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; - $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; - $sql.= ' ORDER BY p.datep, p.tms'; + // Payments already done (from payment on this invoice) + $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,'; + $sql.= ' c.code as payment_code, c.libelle as payment_label,'; + $sql.= ' pf.amount,'; + $sql.= ' ba.rowid as baid, ba.ref, ba.label'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; + $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; + $sql.= ' ORDER BY p.datep, p.tms'; - $result = $db->query($sql); - if ($result) + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + $i = 0; + + //if ($object->type != 2) + //{ + if ($num > 0) { - $num = $db->num_rows($result); - $i = 0; - - //if ($object->type != 2) - //{ - if ($num > 0) + while ($i < $num) { + $objp = $db->fetch_object($result); + $var=!$var; + print ''; + $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label; + print ''; + if (! empty($conf->banque->enabled)) + { + $bankaccountstatic->id=$objp->baid; + $bankaccountstatic->ref=$objp->ref; + $bankaccountstatic->label=$objp->ref; + print ''; + } + print ''; + print ''; + print ''; + $i++; + } + } + else + { + print ''; + } + //} + $db->free($result); + } + else + { + dol_print_error($db); + } + + if ($object->type != 2) + { + // Total already paid + print ''; + + $resteapayeraffiche=$resteapayer; + + // Loop on each credit note or deposit amount applied + $creditnoteamount=0; + $depositamount=0; + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; + $sql.= " re.description, re.fk_facture_source"; + $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; + $sql.= " WHERE fk_facture = ".$object->id; + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + $invoice=new Facture($db); while ($i < $num) { - $objp = $db->fetch_object($result); - $var=!$var; - print ''; - $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label; - print ''; - if (! empty($conf->banque->enabled)) - { - $bankaccountstatic->id=$objp->baid; - $bankaccountstatic->ref=$objp->ref; - $bankaccountstatic->label=$objp->ref; - print ''; - } - print ''; - print ''; - print ''; + $obj = $db->fetch_object($resql); + $invoice->fetch($obj->fk_facture_source); + print ''; + print ''; + print ''; $i++; + if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc; + if ($invoice->type == 3) $depositamount += $obj->amount_ttc; } } else - { - print ''; - } - //} - $db->free($result); - } - else { dol_print_error($db); } - if ($object->type != 2) + // Paye partiellement 'escompte' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat') { - // Total already paid - print ''; - - $resteapayeraffiche=$resteapayer; - - // Loop on each credit note or deposit amount applied - $creditnoteamount=0; - $depositamount=0; - $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; - $sql.= " re.description, re.fk_facture_source"; - $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; - $sql.= " WHERE fk_facture = ".$object->id; - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - $invoice=new Facture($db); - while ($i < $num) - { - $obj = $db->fetch_object($resql); - $invoice->fetch($obj->fk_facture_source); - print ''; - print ''; - print ''; - $i++; - if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc; - if ($invoice->type == 3) $depositamount += $obj->amount_ttc; - } - } - else - { - dol_print_error($db); - } - - // Paye partiellement 'escompte' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat') - { - print ''; - $resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'badcustomer' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer') - { - print ''; - //$resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'product_returned' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned') - { - print ''; - $resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'abandon' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon') - { - print ''; - $resteapayeraffiche=0; - } - - // Billed - print ''; - - // Remainder to pay - print ''; - print ''; - print ''; + print ''; + $resteapayeraffiche=0; } - else // Credit note + // Paye partiellement ou Abandon 'badcustomer' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer') { - // Total already paid back - print ''; - - // Billed - print ''; - - // Remainder to pay back - print ''; - print ''; - print ''; - - // Sold credit note - //print ''; - //print ''; + print ''; + //$resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'product_returned' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned') + { + print ''; + $resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'abandon' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon') + { + print ''; + $resteapayeraffiche=0; } - print '
'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).''.$langs->trans('Type').''.$langs->trans('BankAccount').''.$langs->trans('Amount').' 
'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).''.$langs->trans('Type').''.$langs->trans('BankAccount').''.$langs->trans('Amount').' 
'; + print ''.img_object($langs->trans('ShowPayment'),'payment').' '; + print dol_print_date($db->jdate($objp->dp),'day').''.$label.' '.$objp->num_paiement.''; + if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions'); + print ''.price($sign * $objp->amount).' 
'.$langs->trans("None").'
'; + if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits'); + else print $langs->trans('AlreadyPaid'); + print ' :'.price($totalpaye).' 
'; - print ''.img_object($langs->trans('ShowPayment'),'payment').' '; - print dol_print_date($db->jdate($objp->dp),'day').''.$label.' '.$objp->num_paiement.''; - if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions'); - print ''.price($sign * $objp->amount).' 
'; + if ($invoice->type == 2) print $langs->trans("CreditNote").' '; + if ($invoice->type == 3) print $langs->trans("Deposit").' '; + print $invoice->getNomUrl(0); + print ' :'.price($obj->amount_ttc).''; + print 'rowid.'">'.img_delete().''; + print '
'.$langs->trans("None").'
'; - if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits'); - else print $langs->trans('AlreadyPaid'); - print ' :'.price($totalpaye).' 
'; - if ($invoice->type == 2) print $langs->trans("CreditNote").' '; - if ($invoice->type == 3) print $langs->trans("Deposit").' '; - print $invoice->getNomUrl(0); - print ' :'.price($obj->amount_ttc).''; - print 'rowid.'">'.img_delete().''; - print '
'; - print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - $text=$langs->trans("HelpAbandonOther"); - if ($object->close_note) $text.='

'.$langs->trans("Reason").':'.$object->close_note; - print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1); - print '
'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'.$langs->trans("Billed").' :'.price($object->total_ttc).' 
'; - if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay'); - else print $langs->trans('ExcessReceived'); - print ' :'.price($resteapayeraffiche).' 
'; + print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $langs->trans('AlreadyPaidBack'); - print ' :'.price($sign * $totalpaye).' 
'.$langs->trans("Billed").' :'.price($sign * $object->total_ttc).' 
'; - if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack'); - else print $langs->trans('ExcessPaydBack'); - print ' :'.price($sign * $resteapayeraffiche).' 
'.$langs->trans('TotalTTC').' :'.price($sign * $object->total_ttc).' 
'; + print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + $text=$langs->trans("HelpAbandonOther"); + if ($object->close_note) $text.='

'.$langs->trans("Reason").':'.$object->close_note; + print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1); + print '
'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + // Billed + print '
'.$langs->trans("Billed").' :'.price($object->total_ttc).' 
'; + if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay'); + else print $langs->trans('ExcessReceived'); + print ' :'.price($resteapayeraffiche).' 
'; + print $langs->trans('AlreadyPaidBack'); + print ' :'.price($sign * $totalpaye).' 
'.$langs->trans("Billed").' :'.price($sign * $object->total_ttc).' 
'; + if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack'); + else print $langs->trans('ExcessPaydBack'); + print ' :'.price($sign * $resteapayeraffiche).' 
'.$langs->trans('TotalTTC').' :'.price($sign * $object->total_ttc).' 
'; + + // Margin Infos + if (! empty($conf->margin->enabled)) + { + print '
'; + $object->displayMarginInfos($object->statut > 0); + } + + print '
'; + print ''; + if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentConditionsShort'); + print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; + print '
'; + if ($object->type != 2) + { + if ($action == 'editconditions') { - print '
'; - $object->displayMarginInfos($object->statut > 0); - } - - print '
'; - print ''; - if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('PaymentConditionsShort'); - print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; - print '
'; - if ($object->type != 2) - { - if ($action == 'editconditions') - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); - } - else - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none'); - } + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); } else { - print ' '; + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none'); } - print '
'; - print ''; - if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('DateMaxPayment'); - print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; - print '
'; - if ($object->type != 2) + // Date payment term + print '
'; + print ''; + if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('DateMaxPayment'); + print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; + print '
'; + if ($object->type != 2) + { + if ($action == 'editpaymentterm') { - if ($action == 'editpaymentterm') - { - $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm'); - } - else - { - print dol_print_date($object->date_lim_reglement,'daytext'); - if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late')); - } + $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm'); } else { - print ' '; + print dol_print_date($object->date_lim_reglement,'daytext'); + if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late')); } - print '
'; + print ''; + if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentMode'); + print 'id.'">'.img_edit($langs->trans('SetMode'),1).'
'; + print '
'; + if ($action == 'editmode') + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); + } + else + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none'); + } + print '
'.$langs->trans('AmountHT').''.price($object->total_ht,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('AmountVAT').''.price($object->total_tva,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).'
'; print ''; - if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; print '
'; - print $langs->trans('PaymentMode'); + print $langs->trans('RevenueStamp'); print 'id.'">'.img_edit($langs->trans('SetMode'),1).'id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'
'; - print '
'; - if ($action == 'editmode') + print ''; + if ($action == 'editrevenuestamp') { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); + print '
'; + print ''; + print ''; + print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); + //print ''; + print ' '; + print '
'; } else { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none'); + print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency); } print '
'.$langs->trans('AmountHT').''.price($object->total_ht,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('AmountVAT').''.price($object->total_tva,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('AmountTTC').''.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('Status').''.($object->getLibStatut(4,$totalpaye)).'
'; + + print ''; + if ($action != 'classify') + { + print ''; + } + print '
'; + print $langs->trans('Project'); + print 'id.'">'; + print img_edit($langs->trans('SetProject'),1); + print '
'; + + print '
'; + if ($action == 'classify') + { + $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid'); + } + else + { + $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none'); + } + print '
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).'
'; - print ''; - if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('RevenueStamp'); - print 'id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'
'; - print '
'; - if ($action == 'editrevenuestamp') + $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); + if ($extrafields->attribute_type[$key] == 'separate') { - print ''; - print ''; - print ''; - print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); - //print ''; - print ' '; - print ''; + print $extrafields->showSeparator($key); } else { - print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency); - } - print '
'.$langs->trans('AmountTTC').''.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('Status').''.($object->getLibStatut(4,$totalpaye)).'
'; - - print ''; - if ($action != 'classify') - { - print ''; - } - print '
'; - print $langs->trans('Project'); - print 'id.'">'; - print img_edit($langs->trans('SetProject'),1); - print '
'; - - print '
'; - if ($action == 'classify') - { - $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid'); - } - else - { - $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none'); - } - print '
'; + // Convert date into timestamp format + if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) { - print $extrafields->showSeparator($key); + $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; } - else - { - print '
'; - // Convert date into timestamp format - if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) - { - $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; - } - - if ($action == 'edit_extras' && $user->rights->facture->creer) - { - print $extrafields->showInputField($key,$value); - } - else - { - print $extrafields->showOutputField($key,$value); - } - print '
'; - print ''; - print ''; - print '
'.img_picto('','edit').' '.$langs->trans('Modify').'

'; - - if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) - { - $blocname = 'contacts'; - $title = $langs->trans('ContactsAddresses'); - include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; - } - - if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) - { - $blocname = 'notes'; - $title = $langs->trans('Notes'); - include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; - } - - /* - * Lines - */ - $result = $object->getLinesArray(); - - if (! empty($conf->use_javascript_ajax) && $object->statut == 0) - { - include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; - } - - print ''; - - // Show object lines - if (! empty($object->lines)) - $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1); - - /* - * Form to add new line - */ - if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline') - { - $var=true; - - if ($conf->global->MAIN_FEATURES_LEVEL > 1) - { - // Add free or predefined products/services - $object->formAddObjectLine(1,$mysoc,$soc); - } - else - { - // Add free products/services - $object->formAddFreeProduct(1,$mysoc,$soc); - - // Add predefined products/services - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) + else { - $var=!$var; - $object->formAddPredefinedProduct(1,$mysoc,$soc); + print $extrafields->showOutputField($key,$value); } + print ''."\n"; } - - $parameters=array(); - $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook } - print "
\n"; + if(count($extrafields->attribute_label) > 0) { - print "\n"; - - - /* - * Boutons actions - */ - - if ($action != 'prerelance' && $action != 'presend') - { - if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline') + if ($action == 'edit_extras' && $user->rights->facture->creer) { - print '
'; + print ''; + print ''; + print ''; + print ''; - // Editer une facture deja validee, sans paiement effectue et pas exporte en compta - if ($object->statut == 1) + } + else { + if ($object->statut == 0 && $user->rights->facture->creer) { - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = $object->getVentilExportCompta(); + print ''.img_picto('','edit').' '.$langs->trans('Modify').''; + } + } + } + } - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + print '
'; + + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) + { + $blocname = 'contacts'; + $title = $langs->trans('ContactsAddresses'); + include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; + } + + if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) + { + $blocname = 'notes'; + $title = $langs->trans('Notes'); + include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; + } + + /* + * Lines + */ + $result = $object->getLinesArray(); + + if (! empty($conf->use_javascript_ajax) && $object->statut == 0) + { + include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; + } + + print ''; + + // Show object lines + if (! empty($object->lines)) + $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1); + + /* + * Form to add new line + */ + if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline') + { + $var=true; + + if ($conf->global->MAIN_FEATURES_LEVEL > 1) + { + // Add free or predefined products/services + $object->formAddObjectLine(1,$mysoc,$soc); + } + else + { + // Add free products/services + $object->formAddFreeProduct(1,$mysoc,$soc); + + // Add predefined products/services + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) + { + $var=!$var; + $object->formAddPredefinedProduct(1,$mysoc,$soc); + } + } + + $parameters=array(); + $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + } + + print "
\n"; + + print "
\n"; + + + /* + * Boutons actions + */ + + if ($action != 'prerelance' && $action != 'presend') + { + if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline') + { + print '
'; + + // Editer une facture deja validee, sans paiement effectue et pas exporte en compta + if ($object->statut == 1) + { + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = $object->getVentilExportCompta(); + + if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + { + if (! $objectidnext) { - if (! $objectidnext) + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) - { - print '
'.$langs->trans('Modify').'
'; - } - else - { - print '
'.$langs->trans('Modify').'
'; - } + print '
'.$langs->trans('Modify').'
'; } else { - print '
'.$langs->trans('Modify').'
'; + print '
'.$langs->trans('Modify').'
'; } } - } - - // Reopen a standard paid invoice - if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) // A paid invoice (partially or completely) - { - if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice - { - print '
'.$langs->trans('ReOpen').'
'; - } else { - print '
'.$langs->trans('ReOpen').'
'; + print '
'.$langs->trans('Modify').'
'; } } + } - // Validate - if ($object->statut == 0 && count($object->lines) > 0 && - ( - (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) - || ($object->type == 2 && $object->total_ttc <= 0)) - ) + // Reopen a standard paid invoice + if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) // A paid invoice (partially or completely) + { + if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice { - if ($user->rights->facture->valider) - { - print '
'.$langs->trans('Validate').'
'; - } + print '
'.$langs->trans('ReOpen').'
'; } + else + { + print '
'.$langs->trans('ReOpen').'
'; + } + } - // Send by mail - if (($object->statut == 1 || $object->statut == 2)) + // Validate + if ($object->statut == 0 && count($object->lines) > 0 && + ( + (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) + || ($object->type == 2 && $object->total_ttc <= 0)) + ) + { + if ($user->rights->facture->valider) + { + print '
'.$langs->trans('Validate').'
'; + } + } + + // Send by mail + if (($object->statut == 1 || $object->statut == 2)) + { + if ($objectidnext) + { + print '
'.$langs->trans('SendByMail').'
'; + } + else + { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) + { + print '
'.$langs->trans('SendByMail').'
'; + } + else print '
'.$langs->trans('SendByMail').'
'; + } + } + + if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility + { + if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) { if ($objectidnext) { - print '
'.$langs->trans('SendByMail').'
'; + print '
'.$langs->trans('SendRemindByMail').'
'; } else { if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) { - print '
'.$langs->trans('SendByMail').'
'; + print '
'.$langs->trans('SendRemindByMail').'
'; } - else print '
'.$langs->trans('SendByMail').'
'; + else print '
'.$langs->trans('SendRemindByMail').'
'; } } + } - if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility + // Create payment + if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) + { + if ($objectidnext) { - if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) - { - if ($objectidnext) - { - print '
'.$langs->trans('SendRemindByMail').'
'; - } - else - { - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) - { - print '
'.$langs->trans('SendRemindByMail').'
'; - } - else print '
'.$langs->trans('SendRemindByMail').'
'; - } - } - } - - // Create payment - if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) - { - if ($objectidnext) - { - print '
'.$langs->trans('DoPayment').'
'; - } - else - { - if ($resteapayer == 0) - { - print '
'.$langs->trans('DoPayment').'
'; - } - else - { - print '
'.$langs->trans('DoPayment').'
'; - } - } - } - - // Reverse back money or convert to reduction - if ($object->type == 2 || $object->type == 3) - { - // For credit note only - if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) - { - print '
'.$langs->trans('DoPaymentBack').'
'; - } - // For credit note - if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) - { - print '
'.$langs->trans('ConvertToReduc').'
'; - } - // For deposit invoice - if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer) - { - print '
'.$langs->trans('ConvertToReduc').'
'; - } - } - - // Classify paid (if not deposit and not credit note. Such invoice are "converted") - if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement && - (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) ) - { - print '
'.$langs->trans('ClassifyPaid').'
'; - } - - // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) - if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 - && $user->rights->facture->paiement) - { - if ($totalpaye > 0 || $totalcreditnotes > 0) - { - // If one payment or one credit note was linked to this invoice - print '
'.$langs->trans('ClassifyPaidPartially').'
'; - } - else - { - if ($objectidnext) - { - print '
'.$langs->trans('ClassifyCanceled').'
'; - } - else - { - print '
'.$langs->trans('ClassifyCanceled').'
'; - } - } - } - - // Clone - if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer) - { - print '
'.$langs->trans("ToClone").'
'; - } - - // Clone as predefined - if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer) - { - if (! $objectidnext) - { - print '
'.$langs->trans("ChangeIntoRepeatableInvoice").'
'; - } - } - - // Delete - if ($user->rights->facture->supprimer) - { - if (! $object->is_erasable()) - { - print '
'.$langs->trans('Delete').'
'; - } - else if ($objectidnext) - { - print '
'.$langs->trans('Delete').'
'; - } - elseif ($object->getSommePaiement()) - { - print '
'.$langs->trans('Delete').'
'; - } - else - { - print '
'.$langs->trans('Delete').'
'; - } + print '
'.$langs->trans('DoPayment').'
'; } else { - print '
'.$langs->trans('Delete').'
'; - } - - print '
'; - } - } - print '
'; - - if ($action != 'prerelance' && $action != 'presend') - { - print '
'; - //print '
'; - //print ''; // ancre - - /* - * Documents generes - */ - $filename=dol_sanitizeFileName($object->ref); - $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref); - $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id; - $genallowed=$user->rights->facture->creer; - $delallowed=$user->rights->facture->supprimer; - - print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); - $somethingshown=$formfile->numoffiles; - - /* - * Linked object block - */ - $somethingshown=$object->showLinkedObjectBlock(); - - // Link for paypal payment - if (! empty($conf->paypal->enabled) && $object->statut != 0) - { - include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; - print showPaypalPaymentUrl('invoice',$object->ref); - } - - print '
'; - //print '
'; - - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions=new FormActions($db); - $somethingshown=$formactions->showactions($object,'invoice',$socid); - - //print '
'; - print '
'; - } - else - { - /* - * Affiche formulaire mail - */ - - // By default if $action=='presend' - $titreform='SendBillByMail'; - $topicmail='SendBillRef'; - $action='send'; - $modelmail='facture_send'; - - if ($action == 'prerelance') // For backward compatibility - { - $titrefrom='SendReminderBillByMail'; - $topicmail='SendReminderBillRef'; - $action='relance'; - $modelmail='facture_relance'; - } - - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); - $file=$fileparams['fullname']; - - // Build document if it not exists - if (! $file || ! is_readable($file)) - { - // 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->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - - $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); - $file=$fileparams['fullname']; - } - - print '
'; - print_titre($langs->trans($titreform)); - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->fromtype = 'user'; - $formmail->fromid = $user->id; - $formmail->fromname = $user->getFullName($langs); - $formmail->frommail = $user->email; - $formmail->withfrom=1; - $liste=array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; - $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; - $formmail->withtocc=$liste; - $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; - $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__'); - $formmail->withfile=2; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - // Tableau des substitutions - $formmail->substit['__FACREF__']=$object->ref; - $formmail->substit['__SIGNATURE__']=$user->signature; - $formmail->substit['__PERSONALIZED__']=''; - $formmail->substit['__CONTACTCIVNAME__']=''; - - //Find the good contact adress - $custcontact=''; - $contactarr=array(); - $contactarr=$object->liste_contact(-1,'external'); - - if (is_array($contactarr) && count($contactarr)>0) { - foreach($contactarr as $contact) { - if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { - - require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; - - $contactstatic=new Contact($db); - $contactstatic->fetch($contact['id']); - $custcontact=$contactstatic->getFullName($langs,1); + if ($resteapayer == 0) + { + print '
'.$langs->trans('DoPayment').'
'; + } + else + { + print '
'.$langs->trans('DoPayment').'
'; } } + } - if (!empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__']=$custcontact; + // Reverse back money or convert to reduction + if ($object->type == 2 || $object->type == 3) + { + // For credit note only + if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) + { + print '
'.$langs->trans('DoPaymentBack').'
'; + } + // For credit note + if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) + { + print '
'.$langs->trans('ConvertToReduc').'
'; + } + // For deposit invoice + if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer) + { + print '
'.$langs->trans('ConvertToReduc').'
'; } } - - // Tableau des parametres complementaires du post - $formmail->param['action']=$action; - $formmail->param['models']=$modelmail; - $formmail->param['facid']=$object->id; - $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; - - // Init list of files - if (GETPOST("mode")=='init') + // Classify paid (if not deposit and not credit note. Such invoice are "converted") + if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement && + (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) ) { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + print '
'.$langs->trans('ClassifyPaid').'
'; } - $formmail->show_form(); + // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) + if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 + && $user->rights->facture->paiement) + { + if ($totalpaye > 0 || $totalcreditnotes > 0) + { + // If one payment or one credit note was linked to this invoice + print '
'.$langs->trans('ClassifyPaidPartially').'
'; + } + else + { + if ($objectidnext) + { + print '
'.$langs->trans('ClassifyCanceled').'
'; + } + else + { + print '
'.$langs->trans('ClassifyCanceled').'
'; + } + } + } - print '
'; + // Clone + if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer) + { + print '
'.$langs->trans("ToClone").'
'; + } + + // Clone as predefined + if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer) + { + if (! $objectidnext) + { + print '
'.$langs->trans("ChangeIntoRepeatableInvoice").'
'; + } + } + + // Delete + if ($user->rights->facture->supprimer) + { + if (! $object->is_erasable()) + { + print '
'.$langs->trans('Delete').'
'; + } + else if ($objectidnext) + { + print '
'.$langs->trans('Delete').'
'; + } + elseif ($object->getSommePaiement()) + { + print '
'.$langs->trans('Delete').'
'; + } + else + { + print '
'.$langs->trans('Delete').'
'; + } + } + else + { + print '
'.$langs->trans('Delete').'
'; + } + + print ''; } - } - else - { - dol_print_error($db,$object->error); - } + } + print '
'; + + if ($action != 'prerelance' && $action != 'presend') + { + print '
'; + //print '
'; + //print ''; // ancre + + /* + * Documents generes + */ + $filename=dol_sanitizeFileName($object->ref); + $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref); + $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id; + $genallowed=$user->rights->facture->creer; + $delallowed=$user->rights->facture->supprimer; + + print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); + $somethingshown=$formfile->numoffiles; + + /* + * Linked object block + */ + $somethingshown=$object->showLinkedObjectBlock(); + + // Link for paypal payment + if (! empty($conf->paypal->enabled) && $object->statut != 0) + { + include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; + print showPaypalPaymentUrl('invoice',$object->ref); + } + + print '
'; + //print '
'; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions=new FormActions($db); + $somethingshown=$formactions->showactions($object,'invoice',$socid); + + //print '
'; + print '
'; + } + else + { + /* + * Affiche formulaire mail + */ + + // By default if $action=='presend' + $titreform='SendBillByMail'; + $topicmail='SendBillRef'; + $action='send'; + $modelmail='facture_send'; + + if ($action == 'prerelance') // For backward compatibility + { + $titrefrom='SendReminderBillByMail'; + $topicmail='SendReminderBillRef'; + $action='relance'; + $modelmail='facture_relance'; + } + + $ref = dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); + $file=$fileparams['fullname']; + + // Build document if it not exists + if (! $file || ! is_readable($file)) + { + // 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->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); + $file=$fileparams['fullname']; + } + + print '
'; + print_titre($langs->trans($titreform)); + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->fromtype = 'user'; + $formmail->fromid = $user->id; + $formmail->fromname = $user->getFullName($langs); + $formmail->frommail = $user->email; + $formmail->withfrom=1; + $liste=array(); + foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; + $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; + $formmail->withtocc=$liste; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__'); + $formmail->withfile=2; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->substit['__FACREF__']=$object->ref; + $formmail->substit['__SIGNATURE__']=$user->signature; + $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__CONTACTCIVNAME__']=''; + + //Find the good contact adress + $custcontact=''; + $contactarr=array(); + $contactarr=$object->liste_contact(-1,'external'); + + if (is_array($contactarr) && count($contactarr)>0) { + foreach($contactarr as $contact) { + if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { + + require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; + + $contactstatic=new Contact($db); + $contactstatic->fetch($contact['id']); + $custcontact=$contactstatic->getFullName($langs,1); + } + } + + if (!empty($custcontact)) { + $formmail->substit['__CONTACTCIVNAME__']=$custcontact; + } + } + + + // Tableau des parametres complementaires du post + $formmail->param['action']=$action; + $formmail->param['models']=$modelmail; + $formmail->param['facid']=$object->id; + $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + + // Init list of files + if (GETPOST("mode")=='init') + { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + } + + $formmail->show_form(); + + print '
'; + } } + else + { + dol_print_error($db,$object->error); + } +} - dol_htmloutput_mesg('',$mesgs); +dol_htmloutput_mesg('',$mesgs); - llxFooter(); - $db->close(); - ?> +llxFooter(); +$db->close(); +?> diff --git a/htdocs/compta/journal/purchasesjournal.php b/htdocs/compta/journal/purchasesjournal.php index d3b5e2da41c..2269c0035b9 100755 --- a/htdocs/compta/journal/purchasesjournal.php +++ b/htdocs/compta/journal/purchasesjournal.php @@ -100,12 +100,9 @@ $sql = "SELECT f.rowid, f.ref_supplier, f.type, f.datef, f.libelle,"; $sql.= " fd.total_ttc, fd.tva_tx, fd.total_ht, fd.tva as total_tva, fd.product_type, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2,"; $sql.= " s.rowid as socid, s.nom as name, s.code_compta_fournisseur,"; $sql.= " p.rowid as pid, p.ref as ref, p.accountancy_code_buy,"; -$sql.= " ct.accountancy_code_buy as account_tva, ct.recuperableonly,"; -$sql.= " ctl1.accountancy_code_buy as account_localtax1, ctl2.accountancy_code_buy as account_localtax2"; +$sql.= " ct.accountancy_code_buy as account_tva, ct.recuperableonly"; $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn_det fd"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = fd.fk_product"; $sql.= " JOIN ".MAIN_DB_PREFIX."facture_fourn f ON f.rowid = fd.fk_facture_fourn"; $sql.= " JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid = f.fk_soc" ; @@ -146,6 +143,11 @@ if ($result) $compta_localtax1 = (! empty($obj->account_localtax1)?$obj->account_localtax1:$langs->trans("CodeNotDef")); $compta_localtax2 = (! empty($obj->account_localtax2)?$obj->account_localtax2:$langs->trans("CodeNotDef")); + $account_localtax1=getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc); + $compta_localtax1= (! empty($account_localtax1[2])?$account_localtax1[2]:$langs->trans("CodeNotDef")); + $account_localtax2=getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc); + $compta_localtax2= (! empty($account_localtax2[2])?$account_localtax2[2]:$langs->trans("CodeNotDef")); + $tabfac[$obj->rowid]["date"] = $obj->datef; $tabfac[$obj->rowid]["ref"] = $obj->ref_supplier; $tabfac[$obj->rowid]["type"] = $obj->type; diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php index e1d780fcce4..859c1ff2ea5 100755 --- a/htdocs/compta/journal/sellsjournal.php +++ b/htdocs/compta/journal/sellsjournal.php @@ -102,15 +102,12 @@ $sql = "SELECT f.rowid, f.facnumber, f.type, f.datef, f.ref_client,"; $sql.= " fd.product_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.total_ttc, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2,"; $sql.= " s.rowid as socid, s.nom as name, s.code_compta, s.client,"; $sql.= " p.rowid as pid, p.ref as pref, p.accountancy_code_sell,"; -$sql.= " ct.accountancy_code_sell as account_tva, ct.recuperableonly,"; -$sql.= " ctl1.accountancy_code_sell as account_localtax1, ctl2.accountancy_code_sell as account_localtax2"; +$sql.= " ct.accountancy_code_sell as account_tva, ct.recuperableonly"; $sql.= " FROM ".MAIN_DB_PREFIX."facturedet fd"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = fd.fk_product"; $sql.= " JOIN ".MAIN_DB_PREFIX."facture f ON f.rowid = fd.fk_facture"; $sql.= " JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid = f.fk_soc"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'"; $sql.= " WHERE f.entity = ".$conf->entity; $sql.= " AND f.fk_statut > 0"; if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)"; @@ -129,6 +126,8 @@ if ($result) $tablocaltax2 = array(); $tabttc = array(); $tabcompany = array(); + $account_localtax1=0; + $account_localtax2=0; $num = $db->num_rows($result); $i=0; @@ -147,9 +146,12 @@ if ($result) } $cpttva = (! empty($conf->global->COMPTA_VAT_ACCOUNT)?$conf->global->COMPTA_VAT_ACCOUNT:$langs->trans("CodeNotDef")); $compta_tva = (! empty($obj->account_tva)?$obj->account_tva:$cpttva); - $compta_localtax1 = (! empty($obj->account_localtax1)?$obj->account_localtax1:$langs->trans("CodeNotDef")); - $compta_localtax2 = (! empty($obj->account_localtax2)?$obj->account_localtax2:$langs->trans("CodeNotDef")); + $account_localtax1=getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc); + $compta_localtax1= (! empty($account_localtax1[3])?$account_localtax1[3]:$langs->trans("CodeNotDef")); + $account_localtax2=getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc); + $compta_localtax2= (! empty($account_localtax2[3])?$account_localtax2[3]:$langs->trans("CodeNotDef")); + //la ligne facture $tabfac[$obj->rowid]["date"] = $obj->datef; $tabfac[$obj->rowid]["ref"] = $obj->facnumber; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index b1b26518e95..45683412037 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2848,7 +2848,7 @@ function getLocalTaxesFromRate($vatrate, $local, $thirdparty) dol_syslog("getLocalTaxesFromRate vatrate=".$vatrate." local=".$local." thirdparty id=".(is_object($thirdparty)?$thirdparty->id:'')); // Search local taxes - $sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type"; + $sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type,t.accountancy_code_sell,t.accountancy_code_buy"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_pays as p"; $sql .= " WHERE t.fk_pays = p.rowid AND p.code = '".$thirdparty->country_code."'"; $sql .= " AND t.taux = ".$vatrate." AND t.active = 1"; @@ -2857,9 +2857,9 @@ function getLocalTaxesFromRate($vatrate, $local, $thirdparty) if ($resql) { $obj = $db->fetch_object($resql); - if ($local == 1) return array($obj->localtax1_type, $obj->localtax1); - elseif ($local == 2) return array($obj->localtax2_type, $obj->localtax2); - else return array($obj->localtax1_type, $obj->localtax1, $obj->localtax2_type, $obj->localtax2); + if ($local == 1) return array($obj->localtax1_type, $obj->localtax1,$obj->accountancy_code_sell,$obj->accountancy_code_buy); + elseif ($local == 2) return array($obj->localtax2_type, $obj->localtax2,$obj->accountancy_code_sell,$obj->accountancy_code_buy); + else return array($obj->localtax1_type, $obj->localtax1, $obj->localtax2_type, $obj->localtax2,$obj->accountancy_code_sell,$obj->accountancy_code_buy); } return 0; diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php index 00658b7b9cb..3330f491e70 100644 --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -519,8 +519,12 @@ class doc_generic_order_odt extends ModelePDFCommandes $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index 512bf98be8b..8aa417c83c0 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -497,8 +497,12 @@ class doc_generic_invoice_odt extends ModelePDFFactures $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php index 1fbd02bbe6f..4c81babaa55 100644 --- a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php @@ -650,7 +650,7 @@ class doc_generic_project_odt extends ModelePDFProjects //Time ressources $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note"; - $sql.= ", u.name, u.firstname"; + $sql.= ", u.lastname, u.firstname"; $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; $sql .= " , ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE t.fk_task =".$task->id; @@ -973,8 +973,12 @@ class doc_generic_project_odt extends ModelePDFProjects // Write new file - $odfHandler->saveToDisk($file); - //$odfHandler->exportAsAttachedPDF($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index 26d67f09a32..d4e485562a4 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -482,8 +482,12 @@ class doc_generic_proposal_odt extends ModelePDFPropales $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index acf14c67139..ca93ab1880e 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -313,8 +313,12 @@ class doc_generic_odt extends ModeleThirdPartyDoc $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 7e72eb6f7e2..4f91157438b 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -18,152 +18,152 @@ class OdfException extends Exception class Odf { protected $config = array( - 'ZIP_PROXY' => 'PclZipProxy', // PclZipProxy, PhpZipProxy - 'DELIMITER_LEFT' => '{', - 'DELIMITER_RIGHT' => '}', - 'PATH_TO_TMP' => '/tmp' - ); - protected $file; - protected $contentXml; // To store content of content.xml file - protected $stylesXml; // To store content of styles.xml file - protected $manifestXml; // To store content of META-INF/manifest.xml file - protected $tmpfile; - protected $tmpdir=''; - protected $images = array(); - protected $vars = array(); - protected $segments = array(); - const PIXEL_TO_CM = 0.026458333; - /** - * Class constructor - * - * @param string $filename the name of the odt file - * @throws OdfException - */ - public function __construct($filename, $config = array()) - { - clearstatcache(); + 'ZIP_PROXY' => 'PclZipProxy', // PclZipProxy, PhpZipProxy + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}', + 'PATH_TO_TMP' => '/tmp' + ); + protected $file; + protected $contentXml; // To store content of content.xml file + protected $stylesXml; // To store content of styles.xml file + protected $manifestXml; // To store content of META-INF/manifest.xml file + protected $tmpfile; + protected $tmpdir=''; + protected $images = array(); + protected $vars = array(); + protected $segments = array(); + const PIXEL_TO_CM = 0.026458333; + /** + * Class constructor + * + * @param string $filename the name of the odt file + * @throws OdfException + */ + public function __construct($filename, $config = array()) + { + clearstatcache(); - if (! is_array($config)) { - throw new OdfException('Configuration data must be provided as array'); + if (! is_array($config)) { + throw new OdfException('Configuration data must be provided as array'); + } + foreach ($config as $configKey => $configValue) { + if (array_key_exists($configKey, $this->config)) { + $this->config[$configKey] = $configValue; } - foreach ($config as $configKey => $configValue) { - if (array_key_exists($configKey, $this->config)) { - $this->config[$configKey] = $configValue; - } - } - - $md5uniqid = md5(uniqid()); - if ($this->config['PATH_TO_TMP']) $this->tmpdir = preg_replace('|[\/]$|','',$this->config['PATH_TO_TMP']); // Remove last \ or / - $this->tmpdir .= ($this->tmpdir?'/':'').$md5uniqid; - $this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt'; // We keep .odt extension to allow OpenOffice usage during debug. - - // A working directory is required for some zip proxy like PclZipProxy - if (in_array($this->config['ZIP_PROXY'],array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) { - throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists'); - } - - // Create tmp direcoty (will be deleted in destructor) - if (!file_exists($this->tmpdir)) { - $result=mkdir($this->tmpdir); - } - - // Load zip proxy - $zipHandler = $this->config['ZIP_PROXY']; - if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR',$this->tmpdir); - include_once('zip/'.$zipHandler.'.php'); - if (! class_exists($this->config['ZIP_PROXY'])) { - throw new OdfException($this->config['ZIP_PROXY'] . ' class not found - check your php settings'); - } - $this->file = new $zipHandler($this->tmpdir); - - - if ($this->file->open($filename) !== true) { // This also create the tmpdir directory - throw new OdfException("Error while Opening the file '$filename' - Check your odt filename"); - } - if (($this->contentXml = $this->file->getFromName('content.xml')) === false) { - throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'"); - } - if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) { - throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'"); - } - if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) { - throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'"); - } - $this->file->close(); - - - //print "tmpdir=".$tmpdir; - //print "filename=".$filename; - //print "tmpfile=".$tmpfile; - - copy($filename, $this->tmpfile); - - $this->_moveRowSegments(); } - /** - * Assing a template variable - * - * @param string $key name of the variable within the template - * @param string $value replacement value - * @param bool $encode if true, special XML characters are encoded - * @throws OdfException - * @return odf - */ - public function setVars($key, $value, $encode = true, $charset = 'ISO-8859') - { - $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; - // TODO Warning string may be: - // {aaa} - // instead of {aaa} so we should enhance this function. - //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; - if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { - //if (strpos($this->contentXml, '">'. $key . '') === false) { - throw new OdfException("var $key not found in the document"); - //} - } - $value = $encode ? htmlspecialchars($value) : $value; - $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; - $this->vars[$tag] = str_replace("\n", "", $value); - return $this; + $md5uniqid = md5(uniqid()); + if ($this->config['PATH_TO_TMP']) $this->tmpdir = preg_replace('|[\/]$|','',$this->config['PATH_TO_TMP']); // Remove last \ or / + $this->tmpdir .= ($this->tmpdir?'/':'').$md5uniqid; + $this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt'; // We keep .odt extension to allow OpenOffice usage during debug. + + // A working directory is required for some zip proxy like PclZipProxy + if (in_array($this->config['ZIP_PROXY'],array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) { + throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists'); } - - /** - * Assing a template variable - * - * @param string $key name of the variable within the template - * @param string $value replacement value - * @param bool $encode if true, special XML characters are encoded - * @throws OdfException - * @return odf - */ - public function setVarsHeadFooter($key, $value, $encode = true, $charset = 'ISO-8859') - { - $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; - // TODO Warning string may be: - // {aaa} - // instead of {aaa} so we should enhance this function. - //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; - if (strpos($this->stylesXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { + + // Create tmp direcoty (will be deleted in destructor) + if (!file_exists($this->tmpdir)) { + $result=mkdir($this->tmpdir); + } + + // Load zip proxy + $zipHandler = $this->config['ZIP_PROXY']; + if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR',$this->tmpdir); + include_once('zip/'.$zipHandler.'.php'); + if (! class_exists($this->config['ZIP_PROXY'])) { + throw new OdfException($this->config['ZIP_PROXY'] . ' class not found - check your php settings'); + } + $this->file = new $zipHandler($this->tmpdir); + + + if ($this->file->open($filename) !== true) { // This also create the tmpdir directory + throw new OdfException("Error while Opening the file '$filename' - Check your odt filename"); + } + if (($this->contentXml = $this->file->getFromName('content.xml')) === false) { + throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'"); + } + if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) { + throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'"); + } + if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) { + throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'"); + } + $this->file->close(); + + + //print "tmpdir=".$tmpdir; + //print "filename=".$filename; + //print "tmpfile=".$tmpfile; + + copy($filename, $this->tmpfile); + + $this->_moveRowSegments(); + } + + /** + * Assing a template variable + * + * @param string $key name of the variable within the template + * @param string $value replacement value + * @param bool $encode if true, special XML characters are encoded + * @throws OdfException + * @return odf + */ + public function setVars($key, $value, $encode = true, $charset = 'ISO-8859') + { + $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; + // TODO Warning string may be: + // {aaa} + // instead of {aaa} so we should enhance this function. + //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; + if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { //if (strpos($this->contentXml, '">'. $key . '') === false) { - throw new OdfException("var $key not found in the document"); - //} - } - $value = $encode ? htmlspecialchars($value) : $value; - $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; - $this->vars[$tag] = str_replace("\n", "", $value); - return $this; + throw new OdfException("var $key not found in the document"); + //} } + $value = $encode ? htmlspecialchars($value) : $value; + $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; + $this->vars[$tag] = str_replace("\n", "", $value); + return $this; + } - /** - * Evaluating php codes inside the ODT and output the buffer (print, echo) inplace of the code - * - */ - public function phpEval() - { - preg_match_all('/[\{\<]\?(php)?\s+(?P.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or - for ($i=0;$i < count($matches['content']);$i++) { - try { + /** + * Assing a template variable + * + * @param string $key name of the variable within the template + * @param string $value replacement value + * @param bool $encode if true, special XML characters are encoded + * @throws OdfException + * @return odf + */ + public function setVarsHeadFooter($key, $value, $encode = true, $charset = 'ISO-8859') + { + $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; + // TODO Warning string may be: + // {aaa} + // instead of {aaa} so we should enhance this function. + //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; + if (strpos($this->stylesXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { + //if (strpos($this->contentXml, '">'. $key . '') === false) { + throw new OdfException("var $key not found in the document"); + //} + } + $value = $encode ? htmlspecialchars($value) : $value; + $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; + $this->vars[$tag] = str_replace("\n", "", $value); + return $this; + } + + /** + * Evaluating php codes inside the ODT and output the buffer (print, echo) inplace of the code + * + */ + public function phpEval() + { + preg_match_all('/[\{\<]\?(php)?\s+(?P.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or + for ($i=0;$i < count($matches['content']);$i++) { + try { $ob_output = ''; // flush the output for each code. This var will be filled in by the eval($code) and output buffering : any print or echo or output will be redirected into this variable $code = $matches['content'][$i]; ob_start(); @@ -171,363 +171,400 @@ class Odf $ob_output = ob_get_contents(); // send the content of the buffer into $ob_output $this->contentXml = str_replace($matches[0][$i], $ob_output, $this->contentXml); ob_end_clean(); - } catch (Exception $e) { - ob_end_clean(); - $this->contentXml = str_replace($matches[0][$i], 'ERROR: there was a problem while evaluating this portion of code, please fix it: '.$e, $this->contentXml); - } + } catch (Exception $e) { + ob_end_clean(); + $this->contentXml = str_replace($matches[0][$i], 'ERROR: there was a problem while evaluating this portion of code, please fix it: '.$e, $this->contentXml); } - return 0; } + return 0; + } - /** - * Assign a template variable as a picture - * - * @param string $key name of the variable within the template - * @param string $value path to the picture - * @throws OdfException - * @return odf - */ - public function setImage($key, $value) - { - $filename = strtok(strrchr($value, '/'), '/.'); - $file = substr(strrchr($value, '/'), 1); - $size = @getimagesize($value); - if ($size === false) { - throw new OdfException("Invalid image"); - } - list ($width, $height) = $size; - $width *= self::PIXEL_TO_CM; - $height *= self::PIXEL_TO_CM; - $xml = << IMG; - $this->images[$value] = $file; - $this->setVars($key, $xml, false); - return $this; - } + $this->images[$value] = $file; + $this->setVars($key, $xml, false); + return $this; + } - /** - * Move segment tags for lines of tables - * Called automatically within the constructor - * - * @return void - */ - private function _moveRowSegments() + /** + * Move segment tags for lines of tables + * Called automatically within the constructor + * + * @return void + */ + private function _moveRowSegments() + { + // Search all possible rows in the document + $reg1 = "#]*>(.*)#smU"; + preg_match_all($reg1, $this->contentXml, $matches); + for ($i = 0, $size = count($matches[0]); $i < $size; $i++) { + // Check if the current row contains a segment row.* + $reg2 = '#\[!--\sBEGIN\s(row.[\S]*)\s--\](.*)\[!--\sEND\s\\1\s--\]#sm'; + if (preg_match($reg2, $matches[0][$i], $matches2)) { + $balise = str_replace('row.', '', $matches2[1]); + // Move segment tags around the row + $replace = array( + '[!-- BEGIN ' . $matches2[1] . ' --]' => '', + '[!-- END ' . $matches2[1] . ' --]' => '', + ' '[!-- BEGIN ' . $balise . ' --]' => '[!-- END ' . $balise . ' --]' + ); + $replacedXML = str_replace(array_keys($replace), array_values($replace), $matches[0][$i]); + $this->contentXml = str_replace($matches[0][$i], $replacedXML, $this->contentXml); + } + } + } + + /** + * Merge template variables + * Called automatically for a save + * + * @param string $type 'content' or 'styles' + * @return void + */ + private function _parse($type='content') + { + // Conditionals substitution + // Note: must be done before content substitution, else the variable will be replaced by its value and the conditional won't work anymore + foreach($this->vars as $key => $value) { - // Search all possible rows in the document - $reg1 = "#]*>(.*)#smU"; - preg_match_all($reg1, $this->contentXml, $matches); - for ($i = 0, $size = count($matches[0]); $i < $size; $i++) { - // Check if the current row contains a segment row.* - $reg2 = '#\[!--\sBEGIN\s(row.[\S]*)\s--\](.*)\[!--\sEND\s\\1\s--\]#sm'; - if (preg_match($reg2, $matches[0][$i], $matches2)) { - $balise = str_replace('row.', '', $matches2[1]); - // Move segment tags around the row - $replace = array( - '[!-- BEGIN ' . $matches2[1] . ' --]' => '', - '[!-- END ' . $matches2[1] . ' --]' => '', - ' '[!-- BEGIN ' . $balise . ' --]' => '[!-- END ' . $balise . ' --]' - ); - $replacedXML = str_replace(array_keys($replace), array_values($replace), $matches[0][$i]); - $this->contentXml = str_replace($matches[0][$i], $replacedXML, $this->contentXml); + // If value is true (not 0 nor false nor null nor empty string) + if($value) + { + // Remove the IF tag + $this->contentXml = str_replace('[!-- IF '.$key.' --]', '', $this->contentXml); + // Remove everything between the ELSE tag (if it exists) and the ENDIF tag + $reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy + $this->contentXml = preg_replace($reg, '', $this->contentXml); + } + // Else the value is false, then two cases: no ELSE and we're done, or there is at least one place where there is an ELSE clause, then we replace it + else + { + // Find all conditional blocks for this variable: from IF to ELSE and to ENDIF + $reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy + preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER); + foreach($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause + if (!empty($match[3])) $this->contentXml = str_replace($match[0], $match[3], $this->contentXml); } + // Cleanup the other conditional blocks (all the others where there were no ELSE clause, we can just remove them altogether) + $this->contentXml = preg_replace($reg, '', $this->contentXml); } } - /** - * Merge template variables - * Called automatically for a save - * - * @param string $type 'content' or 'styles' - * @return void - */ - private function _parse($type='content') - { - // Conditionals substitution - // Note: must be done before content substitution, else the variable will be replaced by its value and the conditional won't work anymore - foreach($this->vars as $key => $value) - { - // If value is true (not 0 nor false nor null nor empty string) - if($value) - { - // Remove the IF tag - $this->contentXml = str_replace('[!-- IF '.$key.' --]', '', $this->contentXml); - // Remove everything between the ELSE tag (if it exists) and the ENDIF tag - $reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy - $this->contentXml = preg_replace($reg, '', $this->contentXml); - } - // Else the value is false, then two cases: no ELSE and we're done, or there is at least one place where there is an ELSE clause, then we replace it - else - { - // Find all conditional blocks for this variable: from IF to ELSE and to ENDIF - $reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy - preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER); - foreach($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause - if (!empty($match[3])) $this->contentXml = str_replace($match[0], $match[3], $this->contentXml); - } - // Cleanup the other conditional blocks (all the others where there were no ELSE clause, we can just remove them altogether) - $this->contentXml = preg_replace($reg, '', $this->contentXml); - } - } + // Content (variable) substitution + if ($type == 'content') $this->contentXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->contentXml); + // Styles substitution + if ($type == 'styles') $this->stylesXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->stylesXml); - // Content (variable) substitution - if ($type == 'content') $this->contentXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->contentXml); - // Styles substitution - if ($type == 'styles') $this->stylesXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->stylesXml); + } + /** + * Add the merged segment to the document + * + * @param Segment $segment + * @throws OdfException + * @return odf + */ + public function mergeSegment(Segment $segment) + { + if (! array_key_exists($segment->getName(), $this->segments)) { + throw new OdfException($segment->getName() . 'cannot be parsed, has it been set yet ?'); } + $string = $segment->getName(); + // $reg = '@]*>\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]<\/text:p>@smU'; + $reg = '@\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]@smU'; + $this->contentXml = preg_replace($reg, $segment->getXmlParsed(), $this->contentXml); + return $this; + } - /** - * Add the merged segment to the document - * - * @param Segment $segment - * @throws OdfException - * @return odf - */ - public function mergeSegment(Segment $segment) - { - if (! array_key_exists($segment->getName(), $this->segments)) { - throw new OdfException($segment->getName() . 'cannot be parsed, has it been set yet ?'); - } - $string = $segment->getName(); - // $reg = '@]*>\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]<\/text:p>@smU'; - $reg = '@\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]@smU'; - $this->contentXml = preg_replace($reg, $segment->getXmlParsed(), $this->contentXml); - return $this; - } + /** + * Display all the current template variables + * + * @return string + */ + public function printVars() + { + return print_r('
' . print_r($this->vars, true) . '
', true); + } - /** - * Display all the current template variables - * - * @return string - */ - public function printVars() - { - return print_r('
' . print_r($this->vars, true) . '
', true); - } + /** + * Display the XML content of the file from odt document + * as it is at the moment + * + * @return string + */ + public function __toString() + { + return $this->contentXml; + } - /** - * Display the XML content of the file from odt document - * as it is at the moment - * - * @return string - */ - public function __toString() - { - return $this->contentXml; - } + /** + * Display loop segments declared with setSegment() + * + * @return string + */ + public function printDeclaredSegments() + { + return '
' . print_r(implode(' ', array_keys($this->segments)), true) . '
'; + } - /** - * Display loop segments declared with setSegment() - * - * @return string - */ - public function printDeclaredSegments() - { - return '
' . print_r(implode(' ', array_keys($this->segments)), true) . '
'; - } - - /** - * Declare a segment in order to use it in a loop - * - * @param string $segment - * @throws OdfException - * @return Segment - */ - public function setSegment($segment) - { - if (array_key_exists($segment, $this->segments)) { - return $this->segments[$segment]; - } - // $reg = "#\[!--\sBEGIN\s$segment\s--\]<\/text:p>(.*)\[!--\sEND\s$segment\s--\]#sm"; - $reg = "#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm"; - if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) { - throw new OdfException("'$segment' segment not found in the document"); - } - $this->segments[$segment] = new Segment($segment, $m[1], $this); + /** + * Declare a segment in order to use it in a loop + * + * @param string $segment + * @throws OdfException + * @return Segment + */ + public function setSegment($segment) + { + if (array_key_exists($segment, $this->segments)) { return $this->segments[$segment]; } - /** - * Save the odt file on the disk - * - * @param string $file name of the desired file - * @throws OdfException - * @return void - */ - public function saveToDisk($file = null) - { - if ($file !== null && is_string($file)) { - if (file_exists($file) && !(is_file($file) && is_writable($file))) { - throw new OdfException('Permission denied : can\'t create ' . $file); - } - $this->_save(); - copy($this->tmpfile, $file); - } else { - $this->_save(); - } + // $reg = "#\[!--\sBEGIN\s$segment\s--\]<\/text:p>(.*)\[!--\sEND\s$segment\s--\]#sm"; + $reg = "#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm"; + if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) { + throw new OdfException("'$segment' segment not found in the document"); } - - /** - * Write output file onto disk - * - * @throws OdfException - * @return void - */ - private function _save() - { - $res=$this->file->open($this->tmpfile); // tmpfile is odt template - $this->_parse('content'); - $this->_parse('styles'); - - if (! $this->file->addFromString('content.xml', $this->contentXml)) { - throw new OdfException('Error during file export addFromString'); + $this->segments[$segment] = new Segment($segment, $m[1], $this); + return $this->segments[$segment]; + } + /** + * Save the odt file on the disk + * + * @param string $file name of the desired file + * @throws OdfException + * @return void + */ + public function saveToDisk($file = null) + { + if ($file !== null && is_string($file)) { + if (file_exists($file) && !(is_file($file) && is_writable($file))) { + throw new OdfException('Permission denied : can\'t create ' . $file); } - if (! $this->file->addFromString('styles.xml', $this->stylesXml)) { - throw new OdfException('Error during file export addFromString'); - } - foreach ($this->images as $imageKey => $imageValue) { - // Add the image inside the ODT document - $this->file->addFile($imageKey, 'Pictures/' . $imageValue); - // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice) - $this->addImageToManifest($imageValue); - } - if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) { - throw new OdfException('Error during file export: manifest.xml'); - } - $this->file->close(); - } - - /** - * Update Manifest file according to added image files - * - * @param string $file Image file to add into manifest content - */ - public function addImageToManifest($file) - { - // Get the file extension - $ext = substr(strrchr($val, '.'), 1); - // Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml) - $add = ' '."\n"; - // Append the image to the manifest - $this->manifestXml = str_replace('', $add.'', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything) - } - - /** - * Export the file as attached file by HTTP - * - * @param string $name (optional) - * @throws OdfException - * @return void - */ - public function exportAsAttachedFile($name="") - { $this->_save(); + copy($this->tmpfile, $file); + } else { + $this->_save(); + } + } + + /** + * Write output file onto disk + * + * @throws OdfException + * @return void + */ + private function _save() + { + $res=$this->file->open($this->tmpfile); // tmpfile is odt template + $this->_parse('content'); + $this->_parse('styles'); + + if (! $this->file->addFromString('content.xml', $this->contentXml)) { + throw new OdfException('Error during file export addFromString'); + } + if (! $this->file->addFromString('styles.xml', $this->stylesXml)) { + throw new OdfException('Error during file export addFromString'); + } + foreach ($this->images as $imageKey => $imageValue) { + // Add the image inside the ODT document + $this->file->addFile($imageKey, 'Pictures/' . $imageValue); + // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice) + $this->addImageToManifest($imageValue); + } + if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) { + throw new OdfException('Error during file export: manifest.xml'); + } + $this->file->close(); + } + + /** + * Update Manifest file according to added image files + * + * @param string $file Image file to add into manifest content + */ + public function addImageToManifest($file) + { + // Get the file extension + $ext = substr(strrchr($val, '.'), 1); + // Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml) + $add = ' '."\n"; + // Append the image to the manifest + $this->manifestXml = str_replace('', $add.'', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything) + } + + /** + * Export the file as attached file by HTTP + * + * @param string $name (optional) + * @throws OdfException + * @return void + */ + public function exportAsAttachedFile($name="") + { + $this->_save(); + if (headers_sent($filename, $linenum)) { + throw new OdfException("headers already sent ($filename at $linenum)"); + } + + if( $name == "" ) + { + $name = md5(uniqid()) . ".odt"; + } + + header('Content-type: application/vnd.oasis.opendocument.text'); + header('Content-Disposition: attachment; filename="'.$name.'"'); + header('Content-Length: '.filesize($this->tmpfile)); + readfile($this->tmpfile); + } + + /** + * Convert the ODT file to PDF and export the file as attached file by HTTP + * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh + * + * @param string $name (optional) + * @throws OdfException + * @return void + */ + public function exportAsAttachedPDF($name="") + { + global $conf; + + if( $name == "" ) $name = md5(uniqid()); + + //dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG); + $this->saveToDisk($name); + + $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 + + $name=str_replace('.odt', '', $name); + $command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name; + //dol_syslog('$execmethod='.$execmethod.' Run command='.$command); + if ($execmethod == 1) + { + exec($command, $output_arr, $retval); + } + if ($execmethod == 2) + { + $ok=0; + $handle = fopen($outputfile, 'w'); + if ($handle) + { + dol_syslog("Run command ".$command); + $handlein = popen($command, 'r'); + while (!feof($handlein)) + { + $read = fgets($handlein); + fwrite($handle,$read); + $output_arr[]=$read; + } + pclose($handlein); + fclose($handle); + } + if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } + + if($retval == 0) + { + //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); if (headers_sent($filename, $linenum)) { throw new OdfException("headers already sent ($filename at $linenum)"); } - if( $name == "" ) - { - $name = md5(uniqid()) . ".odt"; + if (!empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + header('Content-type: application/pdf'); + header('Content-Disposition: attachment; filename="'.$name.'.pdf"'); + readfile("$name.pdf"); } + unlink("$name.odt"); + } else { + //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); + //dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG); + echo "Error occured:
"; + foreach($output_arr as $line) + echo $line."
"; + //dol_syslog(get_class($this).'::exportAsAttachedPDF ERROR $line='.$line, LOG_DEBUG); + } + } - header('Content-type: application/vnd.oasis.opendocument.text'); - header('Content-Disposition: attachment; filename="'.$name.'"'); - header('Content-Length: '.filesize($this->tmpfile)); - readfile($this->tmpfile); + /** + * Returns a variable of configuration + * + * @return string The requested variable of configuration + */ + public function getConfig($configKey) + { + if (array_key_exists($configKey, $this->config)) { + return $this->config[$configKey]; + } + return false; + } + /** + * Returns the temporary working file + * + * @return string le chemin vers le fichier temporaire de travail + */ + public function getTmpfile() + { + return $this->tmpfile; + } + + /** + * Delete the temporary file when the object is destroyed + */ + public function __destruct() + { + if (file_exists($this->tmpfile)) { + unlink($this->tmpfile); } - /** - * Convert the ODT file to PDF and export the file as attached file by HTTP - * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh - * - * @param string $name (optional) - * @throws OdfException - * @return void - */ - public function exportAsAttachedPDF($name="") - { - if( $name == "" ) $name = md5(uniqid()); - - $this->saveToDisk("$name.odt"); - exec("./odt2pdf.sh $name",$output,$ret_val); - if($ret_val == 0) - { - if (headers_sent($filename, $linenum)) { - throw new OdfException("headers already sent ($filename at $linenum)"); - } - - header('Content-type: application/pdf'); - header('Content-Disposition: attachment; filename="'.$name.'.pdf"'); - readfile("$name.pdf"); - unlink("$name.odt"); - unlink("$name.pdf"); - } else { - echo "Error occured:
"; - foreach($output as $line) - echo $line."
"; - } + if (file_exists($this->tmpdir)) { + $this->_rrmdir($this->tmpdir); + rmdir($this->tmpdir); } + } - /** - * Returns a variable of configuration - * - * @return string The requested variable of configuration - */ - public function getConfig($configKey) - { - if (array_key_exists($configKey, $this->config)) { - return $this->config[$configKey]; - } - return false; - } - /** - * Returns the temporary working file - * - * @return string le chemin vers le fichier temporaire de travail - */ - public function getTmpfile() - { - return $this->tmpfile; - } - - /** - * Delete the temporary file when the object is destroyed - */ - public function __destruct() - { - if (file_exists($this->tmpfile)) { - unlink($this->tmpfile); - } - - if (file_exists($this->tmpdir)) { - $this->_rrmdir($this->tmpdir); - rmdir($this->tmpdir); - } - } - - /** - * Empty the temporary working directory recursively - * @param $dir the temporary working directory - * @return void - */ - private function _rrmdir($dir) - { - if ($handle = opendir($dir)) { - while (false !== ($file = readdir($handle))) { - if ($file != '.' && $file != '..') { - if (is_dir($dir . '/' . $file)) { - $this->_rrmdir($dir . '/' . $file); - rmdir($dir . '/' . $file); - } else { - unlink($dir . '/' . $file); - } + /** + * Empty the temporary working directory recursively + * @param $dir the temporary working directory + * @return void + */ + private function _rrmdir($dir) + { + if ($handle = opendir($dir)) { + while (false !== ($file = readdir($handle))) { + if ($file != '.' && $file != '..') { + if (is_dir($dir . '/' . $file)) { + $this->_rrmdir($dir . '/' . $file); + rmdir($dir . '/' . $file); + } else { + unlink($dir . '/' . $file); } } - closedir($handle); } + closedir($handle); } + } } ?> \ No newline at end of file diff --git a/htdocs/includes/odtphp/odt2pdf.sh b/htdocs/includes/odtphp/odt2pdf.sh old mode 100644 new mode 100755 diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 41b08dd399f..a76156142d6 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -311,6 +311,8 @@ PaymentConditionShortPT_ORDER=On order PaymentConditionPT_ORDER=On order PaymentConditionShortPT_5050=50-50 PaymentConditionPT_5050=50%% in advance, 50%% on delivery +FixAmount=Fix amount +VarAmount=Variable amount (%% tot.) # PaymentType PaymentTypeVIR=Bank deposit diff --git a/htdocs/langs/es_ES/bills.lang b/htdocs/langs/es_ES/bills.lang index ff1d75eb358..d4146ba2f4e 100644 --- a/htdocs/langs/es_ES/bills.lang +++ b/htdocs/langs/es_ES/bills.lang @@ -287,6 +287,8 @@ TotalOfTwoDiscountMustEqualsOriginal=La suma del importe de los 2 nuevos descuen ConfirmRemoveDiscount=¿Está seguro de querer eliminar este descuento? RelatedBill=Factura asociada RelatedBills=Facturas asociadas +FixAmount=Importe fijo +VarAmount=Importe variable (%% total) # PaymentConditions PaymentConditionShortRECEP=A la recepción diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang index 0c87fb93f66..adfa9a34bdc 100644 --- a/htdocs/langs/fr_FR/bills.lang +++ b/htdocs/langs/fr_FR/bills.lang @@ -322,6 +322,8 @@ PaymentTypeVAD=Paiement en ligne PaymentTypeShortVAD=Paiement en ligne PaymentTypeTRA=Paiement par traite PaymentTypeShortTRA=Traite +FixAmount=Montant Fixe +VarAmount=Montant variable (%% tot.) BankDetails=Coordonnées bancaires BankCode=Code banque