';
+ print '';
+ print "\n";
+
+ print $form->buttonsSaveCancel("Create");
+
+ print "\n";
+ } else {
+ dol_print_error('', "Error, no invoice " . $object->id);
+ }
+} else {
+ /*
+ * View mode
+ */
+ if ($object->id > 0) {
+ $object->fetch($object->id);
+ $object->fetch_thirdparty();
+
+ // Confirmation de la suppression d'une ligne produit
+ if ($action == 'ask_deleteline') {
+ $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
+ }
+
+ // Confirm delete of repeatable invoice
+ if ($action == 'ask_deleteinvoice') {
+ $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteRepeatableInvoice'), $langs->trans('ConfirmDeleteRepeatableInvoice'), 'confirm_deleteinvoice', '', 'no', 1);
+ }
+
+ print $formconfirm;
+
+ $author = new User($db);
+ $author->fetch($object->user_author);
+
+ $head = supplier_invoice_rec_prepare_head($object);
+
+ print dol_get_fiche_head($head, 'card', $langs->trans('RepeatableInvoice'), -1, 'bill'); // Add a div
+
+ // Recurring invoice content
+
+ $linkback = '
' . $langs->trans('BackToList') . ' ';
+
+ $morehtmlref = '';
+ if ($action != 'edittitle') {
+ $morehtmlref .= $form->editfieldkey($object->titre, 'title', $object->titre, $object, $usercancreate, '', '', 0, 2);
+ } else {
+ $morehtmlref .= $form->editfieldval('', 'title', $object->titre, $object, $usercancreate, 'string');
+ }
+ $morehtmlref .= '
';
+ //Ref supplier
+ $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', 0, 1);
+ $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', null, null, '', 1);
+ // Thirdparty
+ $morehtmlref .= '
' . $langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
+
+ // Project
+ if (! empty($conf->projet->enabled)) {
+ $langs->load('projects');
+ $morehtmlref .= '
' . $langs->trans('Project') . ' ';
+ if ($usercancreate) {
+ if ($action != 'classify') {
+ $morehtmlref .= '
' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : ';
+ }
+ if ($action == 'classify') {
+ $morehtmlref .= '
';
+ } else {
+ $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
+ }
+ } else {
+ if (! empty($object->fk_project)) {
+ $project = new Project($db);
+ $project->fetch($object->fk_project);
+ $morehtmlref .= ' : ' . $project->getNomUrl(1);
+ if ($project->title) {
+ $morehtmlref .= ' - ' . $project->title;
+ }
+ } else {
+ $morehtmlref .= '';
+ }
+ }
+ }
+ $morehtmlref .= '
';
+
+ $morehtmlright = '';
+
+ dol_banner_tab($object, 'ref', $linkback, 1, 'title', 'none', $morehtmlref, '', 0, '', $morehtmlright);
+
+ print '
';
+ print '
';
+ print '
';
+
+ print '
';
+
+ print '' . $langs->trans('Author') . ' ';
+ print $author->getNomUrl(-1);
+ print " ";
+
+ // Label
+ print '';
+ print '' . $form->editfieldkey("Label", 'libelle', $object->libelle, $object, $usercancreate) . ' ';
+ print '' . $form->editfieldval("Label", 'libelle', $object->libelle, $object, $usercancreate) . ' ';
+ print ' ';
+
+ print '' . $langs->trans('AmountHT') . ' ';
+ print '' . price($object->total_ht, '', $langs, 1, -1, -1, $conf->currency) . ' ';
+ print ' ';
+
+ print '' . $langs->trans("AmountVAT") . ' ' . price($object->total_tva, '', $langs, 1, -1, -1, $conf->currency) . ' ';
+ print ' ';
+
+ // Amount Local Taxes
+ if (($mysoc->localtax1_assuj == "1" && $mysoc->useLocalTax(1)) || $object->total_localtax1 != 0) { // Localtax1
+ print '' . $langs->transcountry("AmountLT1", $mysoc->country_code) . ' ';
+ print '' . price($object->total_localtax1, 1, '', 1, -1, -1, $conf->currency) . ' ';
+ }
+ if (($mysoc->localtax2_assuj == "1" && $mysoc->useLocalTax(2)) || $object->total_localtax2 != 0) { // Localtax2
+ print '' . $langs->transcountry("AmountLT2", $mysoc->country_code) . ' ';
+ print '' . price($object->total_localtax2, 1, '', 1, -1, -1, $conf->currency) . ' ';
+ }
+
+ print '' . $langs->trans("AmountTTC") . ' ' . price($object->total_ttc, '', $langs, 1, -1, -1, $conf->currency) . ' ';
+ print ' ';
+
+ // Payment term
+ print '';
+ print '';
+ print ' ';
+ 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');
+ }
+
+ print ' ';
+
+ // Payment mode
+ print '';
+ print '';
+ print ' ';
+ if ($action == 'editmode') {
+ $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1);
+ } else {
+ $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->mode_reglement_id, 'none');
+ }
+ print ' ';
+
+ // Multicurrency
+ if (! empty($conf->multicurrency->enabled)) {
+ // Multicurrency code
+ print '';
+ print '';
+ print '';
+ print ' ';
+ $htmlname = (($usercancreate && $action == 'editmulticurrencycode') ? 'multicurrency_code' : 'none');
+ $form->form_multicurrency_code($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_code, $htmlname);
+ print ' ';
+
+ // Multicurrency rate
+ if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
+ print '';
+ print '';
+ print '';
+ print ' ';
+ if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') {
+ if ($action == 'actualizemulticurrencyrate') {
+ list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code);
+ }
+ $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, ($usercancreate ? 'multicurrency_tx' : 'none'), $object->multicurrency_code);
+ } else {
+ $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code);
+ if ($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
+ print '';
+ }
+ }
+ print ' ';
+ }
+ }
+
+ // Help of substitution key
+ $dateexample = dol_now();
+ if (! empty($object->frequency) && ! empty($object->date_when)) {
+ $dateexample = $object->date_when;
+ }
+
+ $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object);
+
+ $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m') . ')';
+ $substitutionarray['__INVOICE_MONTH__'] = $langs->trans("MonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($dateexample, '%m') . ')';
+ $substitutionarray['__INVOICE_NEXT_MONTH__'] = $langs->trans("NextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%m') . ')';
+ $substitutionarray['__INVOICE_PREVIOUS_MONTH_TEXT__'] = $langs->trans("TextPreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%B') . ')';
+ $substitutionarray['__INVOICE_MONTH_TEXT__'] = $langs->trans("TextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($dateexample, '%B') . ')';
+ $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = $langs->trans("TextNextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B') . ')';
+ $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = $langs->trans("PreviousYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'), '%Y') . ')';
+ $substitutionarray['__INVOICE_YEAR__'] = $langs->trans("YearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($dateexample, '%Y') . ')';
+ $substitutionarray['__INVOICE_NEXT_YEAR__'] = $langs->trans("NextYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'), '%Y') . ')';
+ // Only on template invoices
+ $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $langs->trans("DateNextInvoiceBeforeGen") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(($object->date_when ? $object->date_when : dol_now()), 'dayhour') . ')';
+ $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = $langs->trans("DateNextInvoiceAfterGen") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree(($object->date_when ? $object->date_when : dol_now()), $object->frequency, $object->unit_frequency), 'dayhour') . ')';
+ $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $object->nb_gen_done;
+ $substitutionarray['__INVOICE_COUNTER_MAX__'] = $object->nb_gen_max;
+
+ $htmltext = '' . $langs->trans("FollowingConstantsWillBeSubstituted") . ': ';
+ foreach ($substitutionarray as $key => $val) {
+ $htmltext .= $key . ' = ' . $langs->trans($val) . ' ';
+ }
+ $htmltext .= ' ';
+
+ // Note public
+ print '';
+ print $form->editfieldkey($form->textwithpicto($langs->trans('NotePublic'), $htmltext, 1, 'help', '', 0, 2, 'notepublic'), 'note_public', $object->note_public, $object, $usercancreate);
+ print ' ';
+ print $form->editfieldval($langs->trans("NotePublic"), 'note_public', $object->note_public, $object, $usercancreate, 'textarea:' . ROWS_4 . ':90%', '', null, null, '', 1);
+ print ' ';
+ print ' ';
+
+ // Note private
+ print '';
+ print $form->editfieldkey($form->textwithpicto($langs->trans("NotePrivate"), $htmltext, 1, 'help', '', 0, 2, 'noteprivate'), 'note_private', $object->note_private, $object, $usercancreate);
+ print ' ';
+ print $form->editfieldval($langs->trans("NotePrivate"), 'note_private', $object->note_private, $object, $usercancreate, 'textarea:' . ROWS_4 . ':90%', '', null, null, '', 1);
+ print ' ';
+ print ' ';
+
+ // Bank Account
+ print '';
+ print '';
+ print ' ';
+ if ($action == 'editbankaccount') {
+ $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'fk_account', 1);
+ } else {
+ $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'none');
+ }
+ print " ";
+ print ' ';
+
+ // Model pdf
+ print '';
+ print '';
+ print $langs->trans('Model');
+ print ' ';
+ if ($action != 'editmodelpdf' && $usercancreate && $object->statut == FactureFournisseurRec::STATUS_NOTSUSPENDED) {
+ print ' ' . img_edit($langs->trans('SetModel'), 1) . ' ';
+ }
+ print '
';
+ print ' ';
+ if ($action == 'editmodelpdf') {
+ include_once DOL_DOCUMENT_ROOT . '/core/modules/supplier_invoice/modules_facturefournisseur.php';
+ $list = array();
+ $models = ModelePDFSuppliersInvoices::liste_modeles($db);
+ foreach ($models as $k => $model) {
+ $list[] = str_replace(':', '|', $k) . ':' . $model;
+ }
+ $select = 'select;' . implode(',', $list);
+ //TODO : Droits
+ print $form->editfieldval($langs->trans('Model'), 'modelpdf', $object->model_pdf, $object, $usercancreate, $select);
+ } else {
+ print $object->model_pdf;
+ }
+ print " ";
+ print ' ';
+
+ // Other attributes
+ $cols = 2;
+ include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
+
+ print '
';
+
+ print '
';
+ print '
';
+ print '
';
+
+ /*
+ * Recurrence
+ */
+ $title = $langs->trans("Recurrence");
+ //print load_fiche_titre($title, '', 'calendar');
+
+ print '
';
+
+ print '' . img_picto('', 'recurring', 'class="pictofixedwidth"') . $title . ' ';
+
+ // if "frequency" is empty or = 0, the reccurence is disabled
+ print '';
+ print '';
+ print ' ';
+ if ($action == 'editfrequency') {
+ print '';
+ } else {
+ if ($object->frequency > 0) {
+ print $langs->trans('FrequencyPer_' . $object->unit_frequency, $object->frequency);
+ } else {
+ print $langs->trans("NotARecurringInvoiceTemplate");
+ }
+ }
+ print ' ';
+
+ // Date when (next invoice generation)
+ print '';
+ if ($action == 'date_when' || $object->frequency > 0) {
+ print $form->editfieldkey($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $usercancreate, 'day');
+ } else {
+ print $langs->trans("NextDateToExecution");
+ }
+ print ' ';
+ if ($action == 'date_when' || $object->frequency > 0) {
+ print $form->editfieldval($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $usercancreate, 'day', $object->date_when, null, '', '', 0, 'strikeIfMaxNbGenReached');
+ }
+ //var_dump(dol_print_date($object->date_when+60, 'dayhour').' - '.dol_print_date($now, 'dayhour'));
+ if (! $object->isMaxNbGenReached()) {
+ if (! $object->suspended && $action != 'editdate_when' && $object->frequency > 0 && $object->date_when && $object->date_when < $now) {
+ print img_warning($langs->trans("Late"));
+ }
+ } else {
+ print img_info($langs->trans("MaxNumberOfGenerationReached"));
+ }
+ print ' ';
+ print ' ';
+
+ // Max period / Rest period
+ print '';
+ if ($action == 'nb_gen_max' || $object->frequency > 0) {
+ print $form->editfieldkey($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max, $object, $usercancreate);
+ } else {
+ print $langs->trans("MaxPeriodNumber");
+ }
+ print ' ';
+ if ($action == 'nb_gen_max' || $object->frequency > 0) {
+ print $form->editfieldval($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max ? $object->nb_gen_max : '', $object, $usercancreate);
+ } else {
+ print '';
+ }
+ print ' ';
+ print ' ';
+
+ // Status of generated invoices
+ print '';
+ if ($action == 'auto_validate' || $object->frequency > 0) {
+ print $form->editfieldkey($langs->trans("StatusOfGeneratedInvoices"), 'auto_validate', $object->auto_validate, $object, $usercancreate);
+ } else {
+ print $langs->trans("StatusOfGeneratedInvoices");
+ }
+ print ' ';
+ $select = 'select;0:' . $langs->trans('BillStatusDraft') . ',1:' . $langs->trans('BillStatusValidated');
+ if ($action == 'auto_validate' || $object->frequency > 0) {
+ print $form->editfieldval($langs->trans("StatusOfGeneratedInvoices"), 'auto_validate', $object->auto_validate, $object, $usercancreate, $select);
+ }
+ print ' ';
+ // Auto generate documents
+ if (! empty($conf->global->INVOICE_REC_CAN_DISABLE_DOCUMENT_FILE_GENERATION)) {
+ print '';
+ print '';
+ if ($action == 'generate_pdf' || $object->frequency > 0) {
+ print $form->editfieldkey($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', $object->generate_pdf, $object, $usercancreate);
+ } else {
+ print $langs->trans("StatusOfGeneratedDocuments");
+ }
+ print ' ';
+ print '';
+ $select = 'select;0:' . $langs->trans('DoNotGenerateDoc') . ',1:' . $langs->trans('AutogenerateDoc');
+ if ($action == 'generate_pdf' || $object->frequency > 0) {
+ print $form->editfieldval($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', $object->generate_pdf, $object, $usercancreate, $select);
+ }
+ print ' ';
+ print ' ';
+ } else {
+ print ' ';
+ }
+
+ print '
';
+
+ // Frequencry/Recurring section
+ if ($object->frequency > 0) {
+ print '
';
+
+ if (empty($conf->cron->enabled)) {
+ print info_admin($langs->trans("EnableAndSetupModuleCron", $langs->transnoentitiesnoconv("Module2300Name")));
+ }
+
+ print '
';
+ print '
';
+
+ // Nb of generation already done
+ print '' . $langs->trans("NbOfGenerationDone") . ' ';
+ print '';
+ print $object->nb_gen_done ? $object->nb_gen_done : '0';
+ print ' ';
+ print ' ';
+
+ // Date last
+ print '';
+ print $langs->trans("DateLastGeneration");
+ print ' ';
+ print dol_print_date($object->date_last_gen, 'dayhour');
+ print ' ';
+ print ' ';
+
+ print '
';
+
+ print '
';
+ }
+
+ print '
';
+ print '
';
+
+ print '
';
+
+ // Lines
+ print '
\n";
+
+ print dol_get_fiche_end();
+
+ /*
+ * Action bar
+ */
+ print '
';
+
+ if (empty($object->suspended)) {
+ if ($usercancreate) {
+ if (! empty($object->frequency) && $object->nb_gen_max > 0 && ($object->nb_gen_done >= $object->nb_gen_max)) {
+ print '
';
+ } else {
+ if (empty($object->frequency) || $object->date_when <= $nowlasthour) {
+ print '
';
+ } else {
+ print '
';
+ }
+ }
+ } else {
+ print '
';
+ }
+ }
+
+ if ($usercancreate) {
+ if (empty($object->suspended)) {
+ print '
';
+ } else {
+ print '
';
+ }
+ }
+
+ //if ($object->statut == Facture::STATUS_DRAFT && ($user->rights->fournisseur->facture->supprimer || $user->rights->supplier_invoice->supprimer))
+ if (($user->rights->fournisseur->facture->supprimer || $user->rights->supplier_invoice->supprimer)) {
+ print '
';
+ }
+
+ print '
';
+
+ print '
';
+ print '
'; // ancre
+
+ // Show links to link elements
+ $linktoelem = $form->showLinkToObjectBlock($object, null, array('invoice'));
+
+ $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
+
+ print '
';
+ }
+}
+
+// End of page
+llxFooter();
+$db->close();
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index 76159d177c5..b98ef2f8cc6 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -37,6 +37,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
+require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture-rec.class.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
@@ -883,8 +884,52 @@ if (empty($reshook)) {
}
}
+ // Standard invoice or Deposit invoice, created from a Predefined template invoice
+ if ((GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT) && GETPOST('fac_rec', 'int') > 0) {
+ if (empty($dateinvoice)) {
+ $error++;
+ setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
+ $action = 'create';
+ } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
+ $error++;
+ setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
+ $action = 'create';
+ }
+
+ if (!$error) {
+ $object->socid = GETPOST('socid', 'int');
+ $object->type = GETPOST('type');
+ $object->ref = GETPOST('ref');
+ $object->date = $dateinvoice;
+ $object->note_public = trim(GETPOST('note_public', 'restricthtml'));
+ $object->note_private = trim(GETPOST('note_private', 'restricthtml'));
+ $object->ref_client = GETPOST('ref_client');
+ $object->model_pdf = GETPOST('model');
+ $object->fk_project = GETPOST('projectid', 'int');
+ $object->cond_reglement_id = (GETPOST('type') == 3 ? 1 : GETPOST('cond_reglement_id'));
+ $object->mode_reglement_id = GETPOST('mode_reglement_id', 'int');
+ $object->fk_account = GETPOST('fk_account', 'int');
+ $object->amount = price2num(GETPOST('amount'));
+ $object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU');
+ $object->remise_percent = price2num(GETPOST('remise_percent'), '', 2);
+ $object->fk_incoterms = GETPOST('incoterm_id', 'int');
+ $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
+ $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
+ $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int');
+
+ // Source facture
+ $object->fac_rec = GETPOST('fac_rec', 'int');
+ $fac_rec = new FactureFournisseurRec($db);
+ $fac_rec->fetch($object->fac_rec);
+ $fac_rec->fetch_lines();
+ $object->lines = $fac_rec->lines;
+
+ $id = $object->create($user); // This include recopy of links from recurring invoice and recurring invoice lines
+ }
+ }
+
// Standard invoice or Deposit invoice, not from a Predefined template invoice
- if (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT) {
+ if (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT && GETPOST('fac_rec') <= 0) {
if (GETPOST('socid', 'int') < 1) {
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors');
$action = 'create';
@@ -1957,11 +2002,17 @@ if ($action == 'create') {
// Ref
print '
'.$langs->trans('Ref').' '.$langs->trans('Draft').' ';
+ $exampletemplateinvoice = new FactureFournisseurRec($db);
+ $invoice_predefined = new FactureFournisseurRec($db);
+ if (empty($origin) && empty($originid) && GETPOST('fac_rec', 'int') > 0) {
+ $invoice_predefined->fetch(GETPOST('fac_rec', 'int'));
+ }
+
// Third party
print '
'.$langs->trans('Supplier').' ';
print '';
- if ($societe->id > 0) {
+ if ($societe->id > 0 && (!GETPOST('fac_rec', 'int') || !empty($invoice_predefined->frequency))) {
$absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1);
print $societe->getNomUrl(1, 'supplier');
print ' ';
@@ -1973,16 +2024,86 @@ if ($action == 'create') {
$(document).ready(function() {
$("#socid").change(function() {
var socid = $(this).val();
- // reload page
- window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid;
+ var fac_rec = $(\'#fac_rec\').val();
+ window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&fac_rec="+fac_rec;
});
});
';
}
- print ' ';
+ if (!GETPOST('fac_rec', 'int')) {
+ print ' ';
+ }
}
print ' ';
+ // Overwrite some values if creation of invoice is from a predefined invoice
+ if (empty($origin) && empty($originid) && GETPOST('fac_rec', 'int') > 0) {
+ $invoice_predefined->fetch(GETPOST('fac_rec', 'int'));
+
+ $dateinvoice = $invoice_predefined->date_when; // To use next gen date by default later
+ if (empty($projectid)) {
+ $projectid = $invoice_predefined->fk_project;
+ }
+ $cond_reglement_id = $invoice_predefined->cond_reglement_id;
+ $mode_reglement_id = $invoice_predefined->mode_reglement_id;
+ $fk_account = $invoice_predefined->fk_account;
+ $note_public = $invoice_predefined->note_public;
+ $note_private = $invoice_predefined->note_private;
+
+ if (!empty($invoice_predefined->multicurrency_code)) {
+ $currency_code = $invoice_predefined->multicurrency_code;
+ }
+ if (!empty($invoice_predefined->multicurrency_tx)) {
+ $currency_tx = $invoice_predefined->multicurrency_tx;
+ }
+
+ $sql = 'SELECT r.rowid, r.titre as title, r.total_ttc';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_rec as r';
+ $sql .= ' WHERE r.fk_soc = '. (int) $invoice_predefined->socid;
+
+ $resql = $db->query($sql);
+ if ($resql) {
+ $num = $db->num_rows($resql);
+ $i = 0;
+
+ if ($num > 0) {
+ print '
'.$langs->trans('CreateFromRepeatableInvoice').' ';
+ //print ' ';
+ print ''; // We may want to change the template to use
+ print ' ';
+ while ($i < $num) {
+ $objp = $db->fetch_object($resql);
+ print 'rowid) {
+ print ' selected';
+ $exampletemplateinvoice->fetch(GETPOST('fac_rec', 'int'));
+ }
+ print '>'.$objp->title.' ('.price($objp->total_ttc).' '.$langs->trans("TTC").') ';
+ $i++;
+ }
+ print ' ';
+ // Option to reload page to retrieve customer informations. Note, this clear other input
+ if (empty($conf->global->RELOAD_PAGE_ON_TEMPLATE_CHANGE_DISABLED)) {
+ print '';
+ }
+ print ' ';
+ }
+ $db->free($resql);
+ } else {
+ dol_print_error($db);
+ }
+ }
+
// Ref supplier
print '
'.$langs->trans('RefSupplier').' id > 0) {
@@ -2288,6 +2409,34 @@ if ($action == 'create') {
print '';
}
+ // Help of substitution key
+ $htmltext = '';
+ if (GETPOST('fac_rec', 'int') > 0) {
+ $dateexample = $newdateinvoice ? $newdateinvoice : $dateinvoice;
+ if (empty($dateexample)) {
+ $dateexample = dol_now();
+ }
+ $substitutionarray = array(
+ '__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ht).')',
+ '__TOTAL_TTC__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ttc).')',
+ '__INVOICE_PREVIOUS_MONTH__' => $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m').')',
+ '__INVOICE_MONTH__' => $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%m').')',
+ '__INVOICE_NEXT_MONTH__' => $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%m').')',
+ '__INVOICE_PREVIOUS_MONTH_TEXT__' => $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%B').')',
+ '__INVOICE_MONTH_TEXT__' => $langs->trans("TextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%B').')',
+ '__INVOICE_NEXT_MONTH_TEXT__' => $langs->trans("TextNextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B').')',
+ '__INVOICE_PREVIOUS_YEAR__' => $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'), '%Y').')',
+ '__INVOICE_YEAR__' => $langs->trans("YearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%Y').')',
+ '__INVOICE_NEXT_YEAR__' => $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'), '%Y').')'
+ );
+
+ $htmltext = '
'.$langs->trans("FollowingConstantsWillBeSubstituted").': ';
+ foreach ($substitutionarray as $key => $val) {
+ $htmltext .= $key.' = '.$langs->trans($val).' ';
+ }
+ $htmltext .= ' ';
+ }
+
// Intracomm report
if (!empty($conf->intracommreport->enabled)) {
$langs->loadLangs(array("intracommreport"));
@@ -2776,6 +2925,19 @@ if ($action == 'create') {
print '
';
}
}
+
+ if ($object->fk_fac_rec_source > 0) {
+ $tmptemplate = new FactureFournisseurRec($db);
+ $result = $tmptemplate->fetch($object->fk_fac_rec_source);
+ if ($result > 0) {
+ print '
';
+ $link = ''.dol_escape_htmltag($tmptemplate->titre).' ';
+ $s = $langs->transnoentities("GeneratedFromSupplierTemplate", $link);
+
+ print $s;
+ print ' ';
+ }
+ }
print '';
@@ -3559,6 +3721,13 @@ if ($action == 'create') {
print '
id.'&action=clone&socid='.$object->socid.'">'.$langs->trans('ToClone').' ';
}
+ // Clone as predefined / Create template
+ if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_DEPOSIT) && $object->statut == 0 && $usercancreate) {
+ if (!$objectidnext && count($object->lines) > 0) {
+ print '
'.$langs->trans("ChangeIntoRepeatableInvoice").' ';
+ }
+ }
+
// Delete
$isErasable = $object->is_erasable();
if ($action != 'confirm_edit' && ($user->rights->fournisseur->facture->supprimer || ($usercancreate && $isErasable == 1))) { // isErasable = 1 means draft with temporary ref (draft can always be deleted with no need of permissions)
diff --git a/htdocs/fourn/facture/list-rec.php b/htdocs/fourn/facture/list-rec.php
new file mode 100644
index 00000000000..7da3a224d4f
--- /dev/null
+++ b/htdocs/fourn/facture/list-rec.php
@@ -0,0 +1,922 @@
+
+ * Copyright (C) 2004-2016 Laurent Destailleur
+ * Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) 2013 Florian Henry
+ * Copyright (C) 2013 Juanjo Menent
+ * Copyright (C) 2015 Jean-François Ferry
+ * Copyright (C) 2012 Cedric Salvador
+ * Copyright (C) 2015-2021 Alexandre Spangaro
+ * Copyright (C) 2016 Meziane Sof
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file htdocs/compta/facture/invoicetemplate_list.php
+ * \ingroup facture
+ * \brief Page to show list of template/recurring invoices
+ */
+
+require '../../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture-rec.class.php';
+require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+
+// Load translation files required by the page
+$langs->loadLangs(array('bills', 'compta', 'admin', 'other', 'suppliers'));
+
+$action = GETPOST('action', 'alpha');
+$massaction = GETPOST('massaction', 'alpha');
+$show_files = GETPOST('show_files', 'int');
+$confirm = GETPOST('confirm', 'alpha');
+$cancel = GETPOST('cancel', 'alpha');
+$toselect = GETPOST('toselect', 'array');
+$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'invoicetemplatelist'; // To manage different context of search
+$optioncss = GETPOST('optioncss', 'alpha');
+
+$socid = GETPOST('socid', 'int');
+
+// Security check
+$id = (GETPOST('facid', 'int') ?GETPOST('facid', 'int') : GETPOST('id', 'int'));
+$lineid = GETPOST('lineid', 'int');
+$ref = GETPOST('ref', 'alpha');
+if ($user->socid) {
+ $socid = $user->socid;
+}
+$objecttype = 'facture_fourn_rec';
+if ($action == "create" || $action == "add") {
+ $objecttype = '';
+}
+$result = restrictedArea($user, 'facture', $id, $objecttype);
+
+$search_ref = GETPOST('search_ref');
+$search_societe = GETPOST('search_societe');
+$search_montant_ht = GETPOST('search_montant_ht');
+$search_montant_vat = GETPOST('search_montant_vat');
+$search_montant_ttc = GETPOST('search_montant_ttc');
+$search_payment_mode = GETPOST('search_payment_mode');
+$search_payment_term = GETPOST('search_payment_term');
+$search_date_startday = GETPOST('search_date_startday', 'int');
+$search_date_startmonth = GETPOST('search_date_startmonth', 'int');
+$search_date_startyear = GETPOST('search_date_startyear', 'int');
+$search_date_endday = GETPOST('search_date_endday', 'int');
+$search_date_endmonth = GETPOST('search_date_endmonth', 'int');
+$search_date_endyear = GETPOST('search_date_endyear', 'int');
+$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
+$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
+$search_date_when_startday = GETPOST('search_date_when_startday', 'int');
+$search_date_when_startmonth = GETPOST('search_date_when_startmonth', 'int');
+$search_date_when_startyear = GETPOST('search_date_when_startyear', 'int');
+$search_date_when_endday = GETPOST('search_date_when_endday', 'int');
+$search_date_when_endmonth = GETPOST('search_date_when_endmonth', 'int');
+$search_date_when_endyear = GETPOST('search_date_when_endyear', 'int');
+$search_date_when_start = dol_mktime(0, 0, 0, $search_date_when_startmonth, $search_date_when_startday, $search_date_when_startyear); // Use tzserver
+$search_date_when_end = dol_mktime(23, 59, 59, $search_date_when_endmonth, $search_date_when_endday, $search_date_when_endyear);
+$search_recurring = GETPOST('search_recurring', 'int');
+$search_frequency = GETPOST('search_frequency', 'alpha');
+$search_unit_frequency = GETPOST('search_unit_frequency', 'alpha');
+$search_status = GETPOST('search_status', 'int');
+
+$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
+$sortfield = GETPOST('sortfield', 'alpha');
+$sortorder = GETPOST('sortorder', 'alpha');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST('page', 'int');
+if (empty($page) || $page == -1) {
+ $page = 0;
+} // If $page is not defined, or '' or -1
+$offset = $limit * $page;
+if (!$sortorder) {
+ $sortorder = 'DESC';
+}
+if (!$sortfield) {
+ $sortfield = 'f.titre';
+}
+$pageprev = $page - 1;
+$pagenext = $page + 1;
+
+$object = new FactureFournisseurRec($db);
+if (($id > 0 || $ref) && $action != 'create' && $action != 'add') {
+ $ret = $object->fetch($id, $ref);
+ if (!$ret) {
+ setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors');
+ }
+}
+
+// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
+$hookmanager->initHooks(array('supplierinvoicereclist'));
+$extrafields = new ExtraFields($db);
+
+// fetch optionals attributes and labels
+$extrafields->fetch_name_optionals_label($object->table_element);
+
+$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
+
+$permissionnote = $user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php
+$permissiondellink = $user->rights->facture->creer; // Used by the include of actions_dellink.inc.php
+$permissiontoedit = $user->rights->facture->creer; // Used by the include of actions_lineupdonw.inc.php
+
+$arrayfields = array(
+ 'f.titre'=>array('label'=>'Ref', 'checked'=>1),
+ 's.nom'=>array('label'=>'ThirdParty', 'checked'=>1),
+ 'f.total_ht'=>array('label'=>'AmountHT', 'checked'=>1),
+ 'f.total_tva'=>array('label'=>'AmountVAT', 'checked'=>1),
+ 'f.total_ttc'=>array('label'=>'AmountTTC', 'checked'=>1),
+ 'f.fk_mode_reglement'=>array('label'=>'PaymentMode', 'checked'=>0),
+ 'f.fk_cond_reglement'=>array('label'=>'PaymentTerm', 'checked'=>0),
+ 'recurring'=>array('label'=>'RecurringInvoice', 'checked'=>1),
+ 'f.frequency'=>array('label'=>'Frequency', 'checked'=>1),
+ 'f.unit_frequency'=>array('label'=>'FrequencyUnit', 'checked'=>1),
+ 'f.nb_gen_done'=>array('label'=>'NbOfGenerationDoneShort', 'checked'=>1),
+ 'f.date_last_gen'=>array('label'=>'DateLastGenerationShort', 'checked'=>1),
+ 'f.date_when'=>array('label'=>'NextDateToExecutionShort', 'checked'=>1),
+ 'f.fk_user_author'=>array('label'=>'UserCreation', 'checked'=>0, 'position'=>500),
+ 'f.fk_user_modif'=>array('label'=>'UserModification', 'checked'=>0, 'position'=>505),
+ 'f.datec'=>array('label'=>'DateCreation', 'checked'=>0, 'position'=>520),
+ 'f.tms'=>array('label'=>'DateModificationShort', 'checked'=>0, 'position'=>525),
+ 'suspended '=>array('label'=>'Status', 'checked'=>1, 'position'=>1000),
+);
+// Extra fields
+include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
+
+$object->fields = dol_sort_array($object->fields, 'position');
+$arrayfields = dol_sort_array($arrayfields, 'position');
+
+if ($socid > 0) {
+ $tmpthirdparty = new Societe($db);
+ $res = $tmpthirdparty->fetch($socid);
+ if ($res > 0) {
+ $search_societe = $tmpthirdparty->name;
+ }
+}
+$objecttype = 'facture_fourn_rec';
+
+$result = restrictedArea($user, 'facture', $object->id, $objecttype);
+
+
+/*
+ * Actions
+ */
+
+if (GETPOST('cancel', 'alpha')) {
+ $action = 'list';
+ $massaction = '';
+}
+if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
+ $massaction = '';
+}
+
+$parameters = array('socid' => $socid);
+$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
+if ($reshook < 0) {
+ setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+}
+
+if (empty($reshook)) {
+ if (GETPOST('cancel', 'alpha')) {
+ $action = '';
+ }
+
+ // Selection of new fields
+ include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
+
+ // Do we click on purge search criteria ?
+ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers
+ $search_ref = '';
+ $search_societe = '';
+ $search_montant_ht = '';
+ $search_montant_vat = '';
+ $search_montant_ttc = '';
+ $search_payment_mode = '';
+ $search_payment_term = '';
+ $search_date_startday = '';
+ $search_date_startmonth = '';
+ $search_date_startyear = '';
+ $search_date_endday = '';
+ $search_date_endmonth = '';
+ $search_date_endyear = '';
+ $search_date_start = '';
+ $search_date_end = '';
+ $search_date_when_startday = '';
+ $search_date_when_startmonth = '';
+ $search_date_when_startyear = '';
+ $search_date_when_endday = '';
+ $search_date_when_endmonth = '';
+ $search_date_when_endyear = '';
+ $search_date_when_start = '';
+ $search_date_when_end = '';
+ $search_recurring = '';
+ $search_frequency = '';
+ $search_unit_frequency = '';
+ $search_status = '';
+ $search_array_options = array();
+ }
+
+ // Mass actions
+ /*$objectclass='MyObject';
+ $objectlabel='MyObject';
+ $permissiontoread = $user->rights->mymodule->read;
+ $permissiontodelete = $user->rights->mymodule->delete;
+ $uploaddir = $conf->mymodule->dir_output;
+ include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';*/
+}
+
+
+/*
+ * View
+ */
+
+$help_url = '';
+llxHeader('', $langs->trans("RepeatableSupplierInvoices"), $help_url);
+
+$form = new Form($db);
+$formother = new FormOther($db);
+if (!empty($conf->projet->enabled)) {
+ $formproject = new FormProjets($db);
+}
+$companystatic = new Societe($db);
+$supplierinvoicerectmp = new FactureFournisseurRec($db);
+$tmpuser = new User($db);
+
+$now = dol_now();
+$tmparray = dol_getdate($now);
+$today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
+
+
+/*
+ * List mode
+ */
+
+$sql = "SELECT s.nom as name, s.rowid as socid, f.rowid as facid, f.titre as title, f.total_ht, f.total_tva, f.total_ttc, f.frequency, f.unit_frequency,";
+$sql .= " f.nb_gen_done, f.nb_gen_max, f.date_last_gen, f.date_when, f.suspended,";
+$sql .= " f.datec, f.fk_user_author, f.tms, f.fk_user_modif,";
+$sql .= " f.fk_cond_reglement, f.fk_mode_reglement";
+// Add fields from extrafields
+if (!empty($extrafields->attributes[$object->table_element]['label'])) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
+ $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
+ }
+}
+// Add fields from hooks
+$parameters = array();
+$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
+$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
+$sql = preg_replace('/,\s*$/', '', $sql);
+
+$sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s, '.MAIN_DB_PREFIX.'facture_fourn_rec as f';
+$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_rec_extrafields as ef ON ef.fk_object = f.rowid';
+if (empty($user->rights->societe->client->voir) && !$socid) {
+ $sql .= ', '.MAIN_DB_PREFIX.'societe_commerciaux as sc';
+}
+$sql .= ' WHERE f.fk_soc = s.rowid';
+$sql .= ' AND f.entity IN ('.getEntity('invoice').')';
+if (empty($user->rights->societe->client->voir) && !$socid) {
+ $sql .= ' AND s.rowid = sc.fk_soc AND sc.fk_user = '. (int) $user->id;
+}
+if ($search_ref) {
+ $sql .= natural_search('f.titre', $search_ref);
+}
+if ($socid) {
+ $sql .= ' AND s.rowid = '.(int) $socid;
+}
+if ($search_societe) {
+ $sql .= natural_search('s.nom', $search_societe);
+}
+if ($search_montant_ht != '') {
+ $sql .= natural_search('f.total_ht', $search_montant_ht, 1);
+}
+if ($search_montant_vat != '') {
+ $sql .= natural_search('f.total_tva', $search_montant_vat, 1);
+}
+if ($search_montant_ttc != '') {
+ $sql .= natural_search('f.total_ttc', $search_montant_ttc, 1);
+}
+if (!empty($search_payment_mode) && $search_payment_mode != '-1') {
+ $sql .= natural_search('f.fk_mode_reglement', $search_payment_mode, 1);
+}
+if (!empty($search_payment_term) && $search_payment_term != '-1') {
+ $sql .= natural_search('f.fk_cond_reglement', $search_payment_term, 1);
+}
+if ($search_recurring == '1') {
+ $sql .= ' AND f.frequency > 0';
+}
+if ($search_recurring == '0') {
+ $sql .= ' AND (f.frequency IS NULL or f.frequency = 0)';
+}
+if ($search_frequency != '') {
+ $sql .= natural_search('f.frequency', $search_frequency, 1);
+}
+if ($search_unit_frequency != '') {
+ $sql .= ' AND f.frequency > 0'.natural_search('f.unit_frequency', $search_unit_frequency);
+}
+if ($search_status != '' && $search_status >= -1) {
+ if ($search_status == 0) {
+ $sql .= ' AND frequency = 0 AND suspended = 0';
+ }
+ if ($search_status == 1) {
+ $sql .= ' AND frequency != 0 AND suspended = 0';
+ }
+ if ($search_status == -1) {
+ $sql .= ' AND suspended = 1';
+ }
+}
+if ($search_date_start) {
+ $sql .= " AND f.date_last_gen >= '".$db->idate($search_date_start)."'";
+}
+if ($search_date_end) {
+ $sql .= " AND f.date_last_gen <= '".$db->idate($search_date_end)."'";
+}
+if ($search_date_when_start) {
+ $sql .= " AND f.date_when >= '".$db->idate($search_date_when_start)."'";
+}
+if ($search_date_when_end) {
+ $sql .= " AND f.date_when <= '".$db->idate($search_date_when_end)."'";
+}
+
+$tmpsortfield = $sortfield;
+if ($tmpsortfield == 'recurring') {
+ $tmpsortfield = 'f.frequency';
+}
+$sql .= $db->order($tmpsortfield, $sortorder);
+
+$nbtotalofrecords = '';
+if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
+ $result = $db->query($sql);
+ $nbtotalofrecords = $db->num_rows($result);
+ if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
+ $page = 0;
+ $offset = 0;
+ }
+}
+
+$sql .= $db->plimit($limit + 1, $offset);
+
+$resql = $db->query($sql);
+if ($resql) {
+ $num = $db->num_rows($resql);
+
+ $param = '';
+ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
+ $param .= '&contextpage='.urlencode($contextpage);
+ }
+ if ($limit > 0 && $limit != $conf->liste_limit) {
+ $param .= '&limit='.urlencode($limit);
+ }
+ if ($socid > 0) {
+ $param .= '&socid='.urlencode($socid);
+ }
+ if ($search_date_startday) {
+ $param .= '&search_date_startday='.urlencode($search_date_startday);
+ }
+ if ($search_date_startmonth) {
+ $param .= '&search_date_startmonth='.urlencode($search_date_startmonth);
+ }
+ if ($search_date_startyear) {
+ $param .= '&search_date_startyear='.urlencode($search_date_startyear);
+ }
+ if ($search_date_endday) {
+ $param .= '&search_date_endday='.urlencode($search_date_endday);
+ }
+ if ($search_date_endmonth) {
+ $param .= '&search_date_endmonth='.urlencode($search_date_endmonth);
+ }
+ if ($search_date_endyear) {
+ $param .= '&search_date_endyear='.urlencode($search_date_endyear);
+ }
+ if ($search_date_when_startday) {
+ $param .= '&search_date_when_startday='.urlencode($search_date_when_startday);
+ }
+ if ($search_date_when_startmonth) {
+ $param .= '&search_date_when_startmonth='.urlencode($search_date_when_startmonth);
+ }
+ if ($search_date_when_startyear) {
+ $param .= '&search_date_when_startyear='.urlencode($search_date_when_startyear);
+ }
+ if ($search_date_when_endday) {
+ $param .= '&search_date_when_endday='.urlencode($search_date_when_endday);
+ }
+ if ($search_date_when_endmonth) {
+ $param .= '&search_date_when_endmonth='.urlencode($search_date_when_endmonth);
+ }
+ if ($search_date_when_endyear) {
+ $param .= '&search_date_when_endyear='.urlencode($search_date_when_endyear);
+ }
+ if ($search_ref) {
+ $param .= '&search_ref='.urlencode($search_ref);
+ }
+ if ($search_societe) {
+ $param .= '&search_societe='.urlencode($search_societe);
+ }
+ if ($search_montant_ht != '') {
+ $param .= '&search_montant_ht='.urlencode($search_montant_ht);
+ }
+ if ($search_montant_vat != '') {
+ $param .= '&search_montant_vat='.urlencode($search_montant_vat);
+ }
+ if ($search_montant_ttc != '') {
+ $param .= '&search_montant_ttc='.urlencode($search_montant_ttc);
+ }
+ if ($search_payment_mode != '') {
+ $param .= '&search_payment_mode='.urlencode($search_payment_mode);
+ }
+ if ($search_payment_term != '') {
+ $param .= '&search_payment_term='.urlencode($search_payment_term);
+ }
+ if ($search_recurring != '' && $search_recurring != '-1') {
+ $param .= '&search_recurring='.urlencode($search_recurring);
+ }
+ if ($search_frequency > 0) {
+ $param .= '&search_frequency='.urlencode($search_frequency);
+ }
+ if ($search_unit_frequency != '') {
+ $param .= '&search_unit_frequency='.urlencode($search_unit_frequency);
+ }
+ if ($search_status != '') {
+ $param .= '&search_status='.urlencode($search_status);
+ }
+ if ($optioncss != '') {
+ $param .= '&optioncss='.urlencode($optioncss);
+ }
+ // Add $param from extra fields
+ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
+
+ $massactionbutton = $form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge")));
+
+ $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
+ $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
+ //$selectedfields.=$form->showCheckAddButtons('checkforselect', 1);
+
+ print '";
+
+ $db->free($resql);
+} else {
+ dol_print_error($db);
+}
+
+// End of page
+llxFooter();
+$db->close();
diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql
index 55218730381..c76abb14eb1 100644
--- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql
+++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql
@@ -96,4 +96,130 @@ CREATE TABLE llx_stock_mouvement_extrafields (
import_key varchar(14)
)ENGINE=innodb;
+
+-- Facture fourn rec
+CREATE TABLE llx_facture_fourn_rec
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ titre varchar(200) NOT NULL,
+ ref_supplier varchar(180) NOT NULL,
+ entity integer DEFAULT 1 NOT NULL,
+ fk_soc integer NOT NULL,
+ datec datetime,
+ tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ suspended integer DEFAULT 0,
+ libelle varchar(255),
+ amount double(24, 8) DEFAULT 0 NOT NULL,
+ remise real DEFAULT 0,
+ vat_src_code varchar(10) DEFAULT '',
+ localtax1 double(24,8) DEFAULT 0,
+ localtax2 double(24,8) DEFAULT 0,
+ total_ht double(24,8) DEFAULT 0,
+ total_tva double(24,8) DEFAULT 0,
+ total_ttc double(24,8) DEFAULT 0,
+ fk_user_author integer,
+ fk_user_modif integer,
+ fk_projet integer,
+ fk_account integer,
+ fk_cond_reglement integer,
+ fk_mode_reglement integer,
+ date_lim_reglement date,
+ note_private text,
+ note_public text,
+ modelpdf varchar(255),
+ fk_multicurrency integer,
+ multicurrency_code varchar(3),
+ multicurrency_tx double(24,8) DEFAULT 1,
+ multicurrency_total_ht double(24,8) DEFAULT 0,
+ multicurrency_total_tva double(24,8) DEFAULT 0,
+ multicurrency_total_ttc double(24,8) DEFAULT 0,
+ usenewprice integer DEFAULT 0,
+ frequency integer,
+ unit_frequency varchar(2) DEFAULT 'm',
+ date_when datetime DEFAULT NULL,
+ date_last_gen datetime DEFAULT NULL,
+ nb_gen_done integer DEFAULT NULL,
+ nb_gen_max integer DEFAULT NULL,
+ auto_validate integer DEFAULT 0,
+ generate_pdf integer DEFAULT 1
+
+)ENGINE=innodb;
+
+ALTER TABLE llx_facture_fourn_rec ADD UNIQUE INDEX uk_facture_fourn_rec_ref (titre, entity);
+ALTER TABLE llx_facture_fourn_rec ADD UNIQUE INDEX uk_facture_fourn_rec_ref_supplier (ref_supplier, fk_soc, entity);
+ALTER TABLE llx_facture_fourn_rec ADD INDEX idx_facture_fourn_rec_date_lim_reglement (date_lim_reglement);
+ALTER TABLE llx_facture_fourn_rec ADD INDEX idx_facture_fourn_rec_fk_soc (fk_soc);
+ALTER TABLE llx_facture_fourn_rec ADD INDEX idx_facture_fourn_rec_fk_user_author (fk_user_author);
+ALTER TABLE llx_facture_fourn_rec ADD INDEX idx_facture_fourn_rec_fk_projet (fk_projet);
+ALTER TABLE llx_facture_fourn_rec ADD CONSTRAINT fk_facture_fourn_rec_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid);
+ALTER TABLE llx_facture_fourn_rec ADD CONSTRAINT fk_facture_fourn_rec_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid);
+ALTER TABLE llx_facture_fourn_rec ADD CONSTRAINT fk_facture_fourn_rec_fk_projet FOREIGN KEY (fk_projet) REFERENCES llx_projet (rowid);
+
+CREATE TABLE llx_facture_fourn_rec_extrafields
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ fk_object integer NOT NULL,
+ import_key varchar(14) -- import key
+) ENGINE=innodb;
+
+ALTER TABLE llx_facture_fourn_rec_extrafields ADD INDEX idx_facture_fourn_rec_extrafields (fk_object);
+
+CREATE TABLE llx_facture_fourn_det_rec
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ fk_facture_fourn integer NOT NULL,
+ fk_parent_line integer NULL,
+ fk_product integer NULL,
+ ref varchar(50),
+ label varchar(255) DEFAULT NULL,
+ description text,
+ pu_ht double(24,8),
+ pu_ttc double(24,8),
+ qty real,
+ remise_percent real DEFAULT 0,
+ fk_remise_except integer NULL,
+ vat_src_code varchar(10) DEFAULT '',
+ tva_tx double(7,4),
+ localtax1_tx double(7,4) DEFAULT 0,
+ localtax1_type varchar(10) NULL,
+ localtax2_tx double(7,4) DEFAULT 0,
+ localtax2_type varchar(10) NULL,
+ total_ht double(24,8),
+ total_tva double(24,8),
+ total_localtax1 double(24,8) DEFAULT 0,
+ total_localtax2 double(24,8) DEFAULT 0,
+ total_ttc double(24,8),
+ product_type integer DEFAULT 0,
+ date_start integer DEFAULT NULL,
+ date_end integer DEFAULT NULL,
+ info_bits integer DEFAULT 0,
+ special_code integer UNSIGNED DEFAULT 0,
+ rang integer DEFAULT 0,
+ fk_unit integer DEFAULT NULL,
+ import_key varchar(14),
+ fk_user_author integer,
+ fk_user_modif integer,
+ fk_multicurrency integer,
+ multicurrency_code varchar(3),
+ multicurrency_subprice double(24,8) DEFAULT 0,
+ multicurrency_total_ht double(24,8) DEFAULT 0,
+ multicurrency_total_tva double(24,8) DEFAULT 0,
+ multicurrency_total_ttc double(24,8) DEFAULT 0
+)ENGINE=innodb;
+
+ALTER TABLE llx_facture_fourn_det_rec ADD CONSTRAINT fk_facture_fourn_det_rec_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid);
+
+CREATE TABLE llx_facture_fourn_det_rec_extrafields
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ fk_object integer NOT NULL, -- object id
+ import_key varchar(14) -- import key
+)ENGINE=innodb;
+
+ALTER TABLE llx_facture_fourn_det_rec_extrafields ADD INDEX idx_facture_fourn_det_rec_extrafields (fk_object);
+
+ALTER TABLE llx_facture_fourn ADD COLUMN fk_fac_rec_source integer;
+
ALTER TABLE llx_mrp_mo ADD COLUMN fk_parent_line integer;
diff --git a/htdocs/install/mysql/tables/llx_facture_fourn.sql b/htdocs/install/mysql/tables/llx_facture_fourn.sql
index 683f15623a6..9ceff4e4fa9 100644
--- a/htdocs/install/mysql/tables/llx_facture_fourn.sql
+++ b/htdocs/install/mysql/tables/llx_facture_fourn.sql
@@ -61,6 +61,7 @@ create table llx_facture_fourn
fk_user_valid integer, -- user validating
fk_user_closing integer, -- user closing
+ fk_fac_rec_source integer, -- facture rec source
fk_facture_source integer, -- facture origine si facture avoir
fk_projet integer, -- projet auquel est associee la facture
diff --git a/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.extrafields.key.sql b/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.extrafields.key.sql
new file mode 100644
index 00000000000..221f7fa6398
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.extrafields.key.sql
@@ -0,0 +1,20 @@
+-- ========================================================================
+-- Copyright (C) 2017 ATM-CONSULTING
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+-- ===================================================================
+
+
+ALTER TABLE llx_facture_fourn_det_rec_extrafields ADD INDEX llx_facture_fourn_det_rec_extrafields (fk_object);
\ No newline at end of file
diff --git a/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.extrafields.sql b/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.extrafields.sql
new file mode 100644
index 00000000000..096cab080fd
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.extrafields.sql
@@ -0,0 +1,24 @@
+-- ===================================================================
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+-- ===================================================================
+
+create table llx_facture_fourn_det_rec_extrafields
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ fk_object integer NOT NULL, -- object id
+ import_key varchar(14) -- import key
+)ENGINE=innodb;
diff --git a/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.key.sql b/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.key.sql
new file mode 100644
index 00000000000..6d0618c912a
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.key.sql
@@ -0,0 +1,18 @@
+-- ===================================================================
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+-- ===================================================================
+
+ALTER TABLE llx_facture_fourn_det_rec ADD CONSTRAINT fk_facture_fourn_det_rec_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid);
diff --git a/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.sql b/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.sql
new file mode 100644
index 00000000000..8f29f85230a
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_facture_fourn_det_rec.sql
@@ -0,0 +1,61 @@
+-- ===================================================================
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+-- ===================================================================
+
+create table llx_facture_fourn_det_rec
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ fk_facture_fourn integer NOT NULL,
+ fk_parent_line integer NULL,
+ fk_product integer NULL,
+ ref varchar(50), -- supplier product ref
+ label varchar(255) DEFAULT NULL,
+ description text,
+ pu_ht double(24,8), -- unit price excluding tax
+ pu_ttc double(24,8), -- unit price with tax
+ qty real, -- quantity of product/service
+ remise_percent real DEFAULT 0, -- % de la remise ligne (exemple 20%)
+ fk_remise_except integer NULL, -- Lien vers table des remises fixes
+ vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here.
+ tva_tx double(7,4), -- taux tva
+ localtax1_tx double(7,4) DEFAULT 0, -- localtax1 rate
+ localtax1_type varchar(10) NULL, -- localtax1 type
+ localtax2_tx double(7,4) DEFAULT 0, -- localtax2 rate
+ localtax2_type varchar(10) NULL, -- localtax2 type
+ total_ht double(24,8), -- Total HT de la ligne toute quantity et incluant remise ligne et globale
+ total_tva double(24,8), -- Total TVA de la ligne toute quantity et incluant remise ligne et globale
+ total_localtax1 double(24,8) DEFAULT 0, -- Total LocalTax1 for total quantity of line
+ total_localtax2 double(24,8) DEFAULT 0, -- total LocalTax2 for total quantity of line
+ total_ttc double(24,8), -- Total TTC de la ligne toute quantity et incluant remise ligne et globale
+ product_type integer DEFAULT 0,
+ date_start integer DEFAULT NULL, -- date debut si service
+ date_end integer DEFAULT NULL, -- date fin si service
+ info_bits integer DEFAULT 0, -- TVA NPR ou non
+ special_code integer UNSIGNED DEFAULT 0, -- code for special lines
+ rang integer DEFAULT 0, -- ordre d'affichage
+ fk_unit integer DEFAULT NULL,
+ import_key varchar(14),
+
+ fk_user_author integer, -- user making creation
+ fk_user_modif integer, -- user making last change
+
+ fk_multicurrency integer,
+ multicurrency_code varchar(3),
+ multicurrency_subprice double(24,8) DEFAULT 0,
+ multicurrency_total_ht double(24,8) DEFAULT 0,
+ multicurrency_total_tva double(24,8) DEFAULT 0,
+ multicurrency_total_ttc double(24,8) DEFAULT 0
+)ENGINE=innodb;
diff --git a/htdocs/install/mysql/tables/llx_facture_fourn_rec.extrafields.key.sql b/htdocs/install/mysql/tables/llx_facture_fourn_rec.extrafields.key.sql
new file mode 100644
index 00000000000..86dddf51624
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_facture_fourn_rec.extrafields.key.sql
@@ -0,0 +1,19 @@
+-- ===================================================================
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+-- ===================================================================
+
+
+ALTER TABLE llx_facture_fourn_rec_extrafields ADD INDEX idx_facture_fourn_rec_extrafields (fk_object);
diff --git a/htdocs/install/mysql/tables/llx_facture_fourn_rec.extrafields.sql b/htdocs/install/mysql/tables/llx_facture_fourn_rec.extrafields.sql
new file mode 100644
index 00000000000..d1f5bd80e41
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_facture_fourn_rec.extrafields.sql
@@ -0,0 +1,7 @@
+create table llx_facture_fourn_rec_extrafields
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ fk_object integer NOT NULL,
+ import_key varchar(14) -- import key
+) ENGINE=innodb;
\ No newline at end of file
diff --git a/htdocs/install/mysql/tables/llx_facture_fourn_rec.key.sql b/htdocs/install/mysql/tables/llx_facture_fourn_rec.key.sql
new file mode 100644
index 00000000000..b3065fdb5d6
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_facture_fourn_rec.key.sql
@@ -0,0 +1,29 @@
+-- ============================================================================
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+-- ============================================================================
+
+
+ALTER TABLE llx_facture_fourn_rec ADD UNIQUE INDEX uk_facture_fourn_rec_ref (ref, entity);
+ALTER TABLE llx_facture_fourn_rec ADD UNIQUE INDEX uk_facture_fourn_rec_ref_supplier (ref_supplier, fk_soc, entity);
+
+ALTER TABLE llx_facture_fourn_rec ADD INDEX idx_facture_fourn_rec_date_lim_reglement (date_lim_reglement);
+ALTER TABLE llx_facture_fourn_rec ADD INDEX idx_facture_fourn_rec_fk_soc (fk_soc);
+ALTER TABLE llx_facture_fourn_rec ADD INDEX idx_facture_fourn_rec_fk_user_author (fk_user_author);
+ALTER TABLE llx_facture_fourn_rec ADD INDEX idx_facture_fourn_rec_fk_projet (fk_projet);
+
+ALTER TABLE llx_facture_fourn_rec ADD CONSTRAINT fk_facture_fourn_rec_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid);
+ALTER TABLE llx_facture_fourn_rec ADD CONSTRAINT fk_facture_fourn_rec_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid);
+ALTER TABLE llx_facture_fourn_rec ADD CONSTRAINT fk_facture_fourn_rec_fk_projet FOREIGN KEY (fk_projet) REFERENCES llx_projet (rowid);
diff --git a/htdocs/install/mysql/tables/llx_facture_fourn_rec.sql b/htdocs/install/mysql/tables/llx_facture_fourn_rec.sql
new file mode 100644
index 00000000000..edaa49e0ea1
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_facture_fourn_rec.sql
@@ -0,0 +1,77 @@
+-- ===========================================================================
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+-- ===========================================================================
+
+create table llx_facture_fourn_rec
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ titre varchar(200) NOT NULL,
+ ref_supplier varchar(180) NOT NULL,
+ entity integer DEFAULT 1 NOT NULL, -- multi company id
+ fk_soc integer NOT NULL,
+
+ datec datetime, -- date de creation
+ tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- last modification date
+
+ suspended integer DEFAULT 0, -- 1=suspended
+
+ libelle varchar(255),
+ amount double(24, 8) DEFAULT 0 NOT NULL,
+ remise real DEFAULT 0,
+
+ vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here.
+ localtax1 double(24,8) DEFAULT 0,
+ localtax2 double(24,8) DEFAULT 0,
+ total_ht double(24,8) DEFAULT 0,
+ total_tva double(24,8) DEFAULT 0,
+ total_ttc double(24,8) DEFAULT 0,
+
+ fk_user_author integer, -- user creating
+ fk_user_modif integer, -- user making last change
+
+ fk_projet integer, -- projet auquel est associe la facture
+
+ fk_account integer, -- bank account
+ fk_cond_reglement integer, -- condition de reglement (30 jours, fin de mois ...)
+ fk_mode_reglement integer, -- mode de reglement (CHQ, VIR, ...)
+ date_lim_reglement date, -- date limite de reglement
+
+ note_private text,
+ note_public text,
+ modelpdf varchar(255),
+
+ fk_multicurrency integer,
+ multicurrency_code varchar(3),
+ multicurrency_tx double(24,8) DEFAULT 1,
+ multicurrency_total_ht double(24,8) DEFAULT 0,
+ multicurrency_total_tva double(24,8) DEFAULT 0,
+ multicurrency_total_ttc double(24,8) DEFAULT 0,
+
+
+ -- Fields linked to the recurring behavior
+
+ usenewprice integer DEFAULT 0, -- update invoice with current price of product instead of recorded price
+ frequency integer, -- frequency (for example: 3 for every 3 month)
+ unit_frequency varchar(2) DEFAULT 'm', -- 'm' for month (date_when must be a day <= 28), 'y' for year, ...
+
+ date_when datetime DEFAULT NULL, -- date for next gen (when an invoice is generated, this field must be updated with next date)
+ date_last_gen datetime DEFAULT NULL, -- date for last gen (date with last successfull generation of invoice)
+ nb_gen_done integer DEFAULT NULL, -- nb of generation done (when an invoice is generated, this field must incremented)
+ nb_gen_max integer DEFAULT NULL, -- maximum number of generation
+ auto_validate integer DEFAULT 0, -- 0 to create in draft, 1 to create and validate the new invoice
+ generate_pdf integer DEFAULT 1 -- 0 disable pdf, 1 to generate pdf
+
+)ENGINE=innodb;
diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang
index cbce9a6a264..98d83aa9453 100644
--- a/htdocs/langs/en_US/errors.lang
+++ b/htdocs/langs/en_US/errors.lang
@@ -9,6 +9,7 @@ ErrorBadMXDomain=Email %s seems incorrect (domain has no valid MX record)
ErrorBadUrl=Url %s is incorrect
ErrorBadValueForParamNotAString=Bad value for your parameter. It appends generally when translation is missing.
ErrorRefAlreadyExists=Reference %s already exists.
+ErrorTitleAlreadyExists=Title %s already exists.
ErrorLoginAlreadyExists=Login %s already exists.
ErrorGroupAlreadyExists=Group %s already exists.
ErrorEmailAlreadyExists=Email %s already exists.
diff --git a/htdocs/langs/en_US/suppliers.lang b/htdocs/langs/en_US/suppliers.lang
index ca9ee174d29..15da3f0638a 100644
--- a/htdocs/langs/en_US/suppliers.lang
+++ b/htdocs/langs/en_US/suppliers.lang
@@ -47,3 +47,10 @@ BuyerName=Buyer name
AllProductServicePrices=All product / service prices
AllProductReferencesOfSupplier=All references of vendor
BuyingPriceNumShort=Vendor prices
+RepeatableSupplierInvoice=Template supplier invoice
+RepeatableSupplierInvoices=Template supplier invoices
+RepeatableSupplierInvoicesList=Template supplier invoices
+RecurringSupplierInvoices=Recurring supplier invoices
+ToCreateAPredefinedSupplierInvoice=In order to create template supplier invoice, you must create a standard invoice, then, without validating it, click on the "%s" button.
+GeneratedFromSupplierTemplate=Generated from supplier invoice template %s
+SupplierInvoiceGeneratedFromTemplate=Supplier invoice %s Generated from supplier invoice template %s
\ No newline at end of file
diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang
index 80814e27ed2..80d4034a1ba 100644
--- a/htdocs/langs/fr_FR/errors.lang
+++ b/htdocs/langs/fr_FR/errors.lang
@@ -8,7 +8,7 @@ ErrorBadEMail=L'email '%s' est invalide
ErrorBadMXDomain=L'email %s semble incorrect (domaine n'a pas d'enregistrement MX valide)
ErrorBadUrl=L'URL '%s' est invalide
ErrorBadValueForParamNotAString=Mauvaise valeur de paramètre. Ceci arrive lors d'une tentative de traduction d'une clé non renseignée.
-ErrorRefAlreadyExists=Le référence %s existe déjà.
+ErrorRefAlreadyExists=La référence %s existe déjà.
ErrorLoginAlreadyExists=L'identifiant %s existe déjà.
ErrorGroupAlreadyExists=Le groupe %s existe déjà.
ErrorEmailAlreadyExists=L'e-mail %s existe déjà.
diff --git a/htdocs/langs/fr_FR/suppliers.lang b/htdocs/langs/fr_FR/suppliers.lang
index 0d0bf4528a5..dd5402d66ae 100644
--- a/htdocs/langs/fr_FR/suppliers.lang
+++ b/htdocs/langs/fr_FR/suppliers.lang
@@ -46,4 +46,4 @@ ReputationForThisProduct=Réputation
BuyerName=Nom de l'acheteur
AllProductServicePrices=Tous les prix du produits / service
AllProductReferencesOfSupplier=Toutes les références du fournisseur
-BuyingPriceNumShort=Prix fournisseurs
+BuyingPriceNumShort=Prix fournisseurs
\ No newline at end of file