2
0
forked from Wavyzz/dolibarr
Files
dolibarr-fork/htdocs/core/tpl/subtotal_ajaxrow.tpl.php
Yannis Hoareau 1301cd36a1 NEW Subtotal module (#33502)
* Changes to follow mvc logic

* Reworked admin page and form to add lines

* Reworked adding line logic

* Adding options when editing subtotal lines

* Fix translations

* Fixed errors/displays and started pdf

* Color for subtotals pdf lines

* FIX display of subtotal totht

* Added pdf azur for propal

* Fix duplicate translation

* Added subtotal support for facture pdf

* Added subtotal support for commande pdf

* Improve UI/translations

* Restored old pdf

* Info to warn user for unsupported pdf

* Added title lines VAT rate and discount support

This is meant for future feature wich is block mass changing vat rate
and discount percentage

* Working on block apply vat and discount

* Added buttons for block actions

* Handle editing vat and discount for subtotal lines

* Editing vat and discount for subtotal lines bloc working

* Added possibility to move by block

* Updated adding and updating a subtotal line

* Improved vat and discount block update

* Improvement for block vat/discount and line edition

Editing a title line edits the corresponding subtotal line

* Improvement for moving by block

* Bad tile or st line placement managing

* Improved bad title or st line placement managing

* Adding subtotal line improved

Adding a subtotal line adds it right under its corresponding title

* Improved deleting subtotal line

Added possibility to choose if you want to delete the corresponding
subtotal line when deleting a title line

* Preventing too high level titles to be created

* Create and update line errors managing

* Improved bad title or st line placement managing

* Improved st line creation

* improve headers

* fix bad block placement managing

* fix adding st line not working if duplicates titles

* fix translations

* Fix block update

* FIX special chars bug

If special char like " ' " was used in title it could be converted to
special char entity.

* Prepare for pdf options

Pdf options like page break befor title should be shown as a picto if activated on a subtotal line on a document

* Added option managing

* Improved subtotal options and PDF integration

* Code refactor

* Action name/Error managment/PDF refreshing

When adding or updating a subtotal line

* Reformat

* Reworked subtotal options database managment

* Changed access to special code

* Remove unecessary call to php trait

* Changed definition of subtotals special code constant

* Reworked align on PDF

* Removed unecessary function and improved error managment

* Typo fix and removed treated todos

* Post typo changed for to better match subtotals names

* Disabled edit if status is not draft

* Changed way subtotals options are stored

* Added view managing when creating a document form an other

* Improved creating document from an other

Can check subtotals lines with table head checkbox and removed highlight
class for better UI.

* Make include of subtotals tpl more clear

* Manage centered or justified case

If user chose to center or justify, we don't change nothing

* Improved pdf

* Removed unecessary code block

* optimisation

* Code sniffer fix

* Code sniffer fix

* Code sniffer fix

* Code sniffer fix

* Code sniffer fix and added missing translation

* Fix php code sniffer

* Reload page when setup saved on subtotals admin page

* Fix php code sniffer

* pjan fix

* phan fix

* phan fix

* phan fix

* phan fix

* phan fix

* phan fix

* phan fix

* phan fix

* phan fix

* phan fix

* phan fix

* php warning fix

* php warning fix

* php phan fix

* php phan fix

* php phan fix

* Fix bug admin page not loading because of const not defined

* php phan fix

* php phan fix

* FIX subtotals admin page display

* php phan fix

* FIX php phan

* Fix bugs and langs

* Fix bug pdf align

* Replace include by require

* Add headers to avoid refreshing and adding unwanted lines

* Fix phan

* Add GETPOST check for security

* Fix phan

* Fix phan

* Fix phan

* Subtotal option when creating a document from another

* Fix phan

* Add field subtotal options for subtotal lines

* Fix phan

* Fix phan

* Fix phan

* Update to follow mvc

* Fix php phan

* Fix php phan

* Fix phpstan/phan

* Fix phpstan

* Fix phpstan

* Fix phpstan

* Fix phpstan

* Fix phpstan

* Update to switch to extraparams

* Update to switch to extraparams

* Retrieve extraparams from db to objectline

* Modified last things to switch to extraparams

* Cleaning unnecessary code lines

* Fix php-stan

* Section subtotal in extraparams to differentiate if needed for further devs

* Fix phan

* Keep extraparams when creating from another object

* Change default value to false when creating a subtotal line

* Fix clone would not keep extraparams in new object

* Fix dark subtotal line background color

Fix when a subtotal background color is too dark and edit pencil or
delete trash could not be seen

* Fix typo

* Fix typo

* Added subtotals for facturerec

* Fix precommit

* Added extraparams when creating rec from fac and other way

* Fix phan

* Fix objectline null

* Desactivating block vat / discount update for facturerec

* reformating code

* Added expeditions for subtotal

* Save extraparams for shipping lines

* Display of subtotals lines in shipments

* Display when creating facture from shipments

* Improve display of lines and invoice creation from shipments

* Fix error if missing line rang

* Deleted duplicate

* Added deletion of subtotal line in shipping documents

* Not including subtotal lines if there is no product line in between

* Update get subtotal lines in shipment docs to disable

* Delete possibility to edit subtotal lines in shipments

* Handle pdf for shipment

* Handle conf stock or shipment supporting services

* Fix precommit

* Fix duplicate name creating bug

* Fix bug where id could be changed by the line id and would create bug

* Deleted subtotal lines when STOCK_SUPPORTS_SERVICES is enabled and block would only have service lines

* Disable shipments in admin modules

Shimpements subtotals lines are only created from commands

* Fixing phan and stan

* Deleted unused template and phan fix

* Fix phan

* Fix phan

* Fix phan

* FIX: phan

* Fix template bug

If document was not in subtotal scope and would use a template used by
subtotal it would create an error.

* Fix php-stan

* Fix bad display when modules and confs were activated

* Fix php codesniffer

* Excluding subtotal lines when mass updating

* Fix shipments service lines exluded + showing subtotal line with specific configs

* Fix line display with situation invoices + bug block line update

* Added ODT managment

This works with invoices but has not been tested with other documents

* Fix bug when editing VAT/discount by block

* Fix error raised when subtotal line added

Subtotal line had no fk_product and raised the error but we want this
line to have no fk product

* Fix precommit

* Added ODT template for documents that uses subtotals

This template can be usefull to understand how to create an odt template
using subtotals module

* Fix phan

* Fix phan

* fix: buttons showing in bad document status

* clean: unwanted commited files

* add: table examples to use with subtotals on ODT templates

* fix: Unwanted print of value when creating a document from another

* feat: renaming for better understanding

* feat: Improved templates for documents related to subtotals

---------

Co-authored-by: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-05-10 02:44:31 +02:00

300 lines
11 KiB
PHP

<?php
/* Copyright (C) 2014-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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 <https://www.gnu.org/licenses/>.
* or see https://www.gnu.org/
*/
/**
* Javascript code to activate the drag and drop on lines
* while using subtotal module
* You can use this if you want to be able to drag and drop rows of a HTML table.
* You must add id="tablelines" on table level tag
* $object and $object->id must be defined
* $object->fk_element or $fk_element must be defined
* you must have ($nboflines or count($object->lines) or count($taskarray) > 0)
* you must have $table_element_line = 'tablename' or $object->table_element_line with line to move
*
*/
/**
* @var Conf $conf
* @var CommonObject $object
* @var Translate $langs
*
* @var ?string $filepath
* @var ?string $fk_element
* @var ?int $nboflines
* @var ?string $tagidfortablednd
*/
// Protection to avoid direct call of template
if (empty($object) || !is_object($object)) {
print "Error, template page ".basename(__FILE__)." can't be called with no object defined.";
exit;
}
'
@phan-var-force ?string $fk_element
@phan-var-force ?Task[] $tasksarray
';
?>
<!-- BEGIN PHP TEMPLATE SUBTOTAL_AJAXROW.TPL.PHP - Script to enable drag and drop on lines of a table using subtotal lines -->
<?php
$id = $object->id;
$fk_element = empty($object->fk_element) ? $fk_element : $object->fk_element;
$table_element_line = (empty($table_element_line) ? $object->table_element_line : $table_element_line);
$nboflines = count($object->lines);
$forcereloadpage = !getDolGlobalString('MAIN_FORCE_RELOAD_PAGE') ? 0 : 1;
$tagidfortablednd = (empty($tagidfortablednd) ? 'tablelines' : $tagidfortablednd);
$filepath = (empty($filepath) ? '' : $filepath);
$langs->load("subtotals");
if (GETPOST('action', 'aZ09') != 'editline' && $nboflines > 1 && $conf->browser->layout != 'phone') { ?>
<div id="notification-message" hidden=""></div>
<script>
function openDialog() {
jQuery(function() {
jQuery("#notification-message").dialog({
resizable: false,
modal: true,
buttons: {
Ok: function() {
jQuery(this).dialog('close');
}
}
});
});
}
function init(){
$(".imgupforline").hide();
$(".imgdownforline").hide();
$(".lineupdown").removeAttr('href');
console.log($(".tdlineupdown"));
$(".tdlineupdown").each(function (tdindex, tdline) {
var gripimg = tdline.dataset.gripimg ?? 'grip.png';
console.log(gripimg);
$(tdline).css("background-image",'url(<?php echo DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/'; ?>' + gripimg + ')');
$(tdline).css("background-repeat","no-repeat");
$(tdline).css("background-position","center center");
console.log($(".tdlineupdown")[tdindex], tdline);
})
console.log("Prepare tableDnd for #<?php echo $tagidfortablednd; ?>");
var inital_table = $("#<?php echo $tagidfortablednd; ?> .drag").map((_, el) => $(el)[0]).get();
var rowsToMove = [];
$("#<?php echo $tagidfortablednd; ?>").tableDnD({
onDragStart: function (table, row) {
if (row.parentNode.dataset.level > 0) {
var hide = false;
$("#<?php echo $tagidfortablednd; ?> .drag").each(
function (intIndex) {
if (hide) {
if ($(this)[0].dataset.level>-row.parentNode.dataset.level && $(this)[0].dataset.level<=row.parentNode.dataset.level) {
hide = false;
return false;
}
rowsToMove.unshift($(this));
if (Math.abs($(this)[0].dataset.level) <= Math.abs(row.parentNode.dataset.level)) {
hide = false;
}
}
if ($(this)[0].id === row.parentNode.id) {
rowsToMove.unshift($(this));
hide = true;
}
});
if (!hide) {
rowsToMove.forEach(function ($hiddenRow, i) {
if (i<rowsToMove.length-1) {
$hiddenRow.hide();
}
});
} else {
rowsToMove = [];
}
}
},
onDragStop: function(table, row) {
if (rowsToMove.length !== 0) {
rowsToMove.forEach(function (hiddenRow) {
hiddenRow.insertAfter($("#" + row.id));
hiddenRow.show();
});
rowsToMove = [];
}
if (row.dataset.desc !== undefined) {
checkLinePosition(row, inital_table);
}
inital_table = $("#<?php echo $tagidfortablednd; ?> .drag").map((_, el) => $(el)[0]).get();
var reloadpage = "<?php echo $forcereloadpage; ?>";
console.log("tableDND onDrop");
console.log(decodeURI($("#<?php echo $tagidfortablednd; ?>").tableDnDSerialize()));
$('#<?php echo $tagidfortablednd; ?> tr[data-element=extrafield]').attr('id', ''); // Set extrafields id to empty value in order to ignore them in tableDnDSerialize function
$('#<?php echo $tagidfortablednd; ?> tr[data-ignoreidfordnd=1]').attr('id', ''); // Set id to empty value in order to ignore them in tableDnDSerialize function
var roworder = cleanSerialize(decodeURI($("#<?php echo $tagidfortablednd; ?>").tableDnDSerialize()));
var table_element_line = "<?php echo $table_element_line; ?>";
var fk_element = "<?php echo $fk_element; ?>";
var element_id = "<?php echo $id; ?>";
var filepath = "<?php echo urlencode($filepath); ?>";
var token = "<?php echo currentToken(); ?>"; // We use old 'token' and not 'newtoken' for Ajax call because the ajax page has the NOTOKENRENEWAL constant set.
$.post("<?php echo DOL_URL_ROOT; ?>/core/ajax/row.php",
{
roworder: roworder,
table_element_line: table_element_line,
fk_element: fk_element,
element_id: element_id,
filepath: filepath,
token: token
},
function() {
console.log("tableDND end of ajax call");
console.log(roworder, table_element_line, fk_element, element_id, filepath, token);
if (reloadpage == 1) {
<?php
$redirectURL = empty($urltorefreshaftermove) ? ($_SERVER['PHP_SELF'].'?'.dol_escape_js($_SERVER['QUERY_STRING'])) : $urltorefreshaftermove;
// remove action parameter from URL
$redirectURL = preg_replace('/(&|\?)action=[^&#]*/', '', $redirectURL);
?>
location.href = '<?php echo dol_escape_js($redirectURL); ?>';
}
});
},
onDragClass: "dragClass",
dragHandle: "td.tdlineupdown"
});
$(".tdlineupdown").hover( function() { $(this).addClass('showDragHandle'); },
function() { $(this).removeClass('showDragHandle'); }
);
}
function checkLinePosition(row, inital_table) {
const tbody = $("#<?php echo $tagidfortablednd; ?> .drag").map((_, el) => $(el)[0]).get();
for (var k = 0; k < tbody.length; k++) {
const currentRow = tbody[k];
if (currentRow.dataset.rang !== undefined) {
currentRow.dataset.rang = k+1;
}
}
var rowLevel = parseInt(row.dataset.level);
var cancelLineMove = false;
var found_title = rowLevel >= 0;
var ignore_level = 0;
for (var i = row.dataset.rang-2; i >= 0; i--) {
if (tbody[i].dataset.desc !== undefined) {
const currentRowLevel1 = parseInt(tbody[i].dataset.level, 10);
console.log(currentRowLevel1, -rowLevel, currentRowLevel1 < -rowLevel);
if (rowLevel > 0) {
// Title line placement managing
if (currentRowLevel1 <= ignore_level && ignore_level !== 0) {
console.log("here");
// continue
} else if (-currentRowLevel1 === rowLevel) {
break;
} else if (currentRowLevel1 > 0 && currentRowLevel1 < rowLevel) {
if (rowLevel - currentRowLevel1 > 1) {
$("#notification-message").text("<?php echo $langs->trans("PreviousTitleLevelTooHigh"); ?>");
cancelLineMove = true;
break;
}
break;
// console.log(tbody[i].dataset.desc, currentRowLevel1, rowLevel);
} else if (currentRowLevel1 === rowLevel) {
for (var j = row.dataset.rang; j < tbody.length; j++) {
if (tbody[j].dataset.desc !== undefined) {
const currentRowLevel2 = parseInt(tbody[j].dataset.level, 10);
if (tbody[i].dataset.desc === tbody[j].dataset.desc && currentRowLevel1 === -currentRowLevel2) {
$("#notification-message").text("<?php echo $langs->trans("TitleUnderSameLevelSTLine"); ?>");
cancelLineMove = true;
break;
}
}
}
} else if (currentRowLevel1 > rowLevel) {
for (var j = row.dataset.rang; j < tbody.length; j++) {
if (tbody[j].dataset.desc !== undefined) {
const currentRowLevel2 = parseInt(tbody[j].dataset.level, 10);
if (row.dataset.desc !== tbody[j].dataset.desc && currentRowLevel2 <= -rowLevel) {
$("#notification-message").text("<?php echo $langs->trans("TitleAfterStLineOfSameLevelTitle"); ?>");
cancelLineMove = true;
break;
}
}
}
break;
} else if (currentRowLevel1 < -rowLevel) {
ignore_level = currentRowLevel1;
} else {
$("#notification-message").text("<?php echo $langs->trans("TitleUnderSameLevelOrGreater"); ?>");
cancelLineMove = true;
break;
}
} else if (rowLevel < 0) {
// Subtotal line placement managing
if (currentRowLevel1 < 0 && rowLevel <= currentRowLevel1 || currentRowLevel1 >0 && -rowLevel >= currentRowLevel1) {
console.log(rowLevel, currentRowLevel1);
if (tbody[i].dataset.desc === row.dataset.desc) {
found_title = true;
break;
}else if (-rowLevel === currentRowLevel1) {
$("#notification-message").text("<?php echo $langs->trans("STLineUnderCorrespondingTitleDesc"); ?>");
cancelLineMove = true;
break;
} else if (-rowLevel > currentRowLevel1) {
$("#notification-message").text("<?php echo $langs->trans("STLineUnderCorrespondingTitle"); ?>");
cancelLineMove = true;
break;
}
}
}
}
}
if (!found_title) {
$("#notification-message").text("<?php echo $langs->trans("STLineUnderTitle"); ?>");
cancelLineMove = true;
}
if (cancelLineMove) {
const tbody_to_replace = $(row).parent()[0];
$(tbody_to_replace).empty();
$(tbody_to_replace).append(inital_table);
init();
openDialog();
}
}
$(document).ready(function(){
init()
});
</script>
<?php } else { ?>
<script>
$(document).ready(function(){
$(".imgupforline").hide();
$(".imgdownforline").hide();
$(".lineupdown").removeAttr('href');
});
</script>
<?php } ?>
<!-- END PHP TEMPLATE AJAXROW.TPL.PHP -->