dolibarr.deliveryinvoiceadd.../core/substitutions/functions_deliveryinvoiceaddress.lib.php
data e8694aa0a4 v1.2: Fix name-Substitution, neuer fullname-Platzhalter, Code-Refactoring
- Fix: {*_contact_name} liefert jetzt Nachname statt Vorname
- Neu: {*_contact_fullname} (Vorname + Nachname, MAIN_FIRSTNAME_NAME_POSITION)
- Refactoring: eine JOIN-Query statt N+1, Mapping-Array, Elementtyp-Check
- Dokumentation aktualisiert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:23:27 +01:00

95 lines
3.7 KiB
PHP
Executable file

<?php
/**
* Substitution-Funktion für Kontaktadressen in Dokumenten.
*
* Unterstützt Angebote (propal), Aufträge (commande) und Rechnungen (facture).
* Stellt Platzhalter für Rechnungs-, Service- und Lieferkontakte bereit:
* {billing_contact_firstname}, {billing_contact_name}, {billing_contact_fullname},
* {billing_contact_address}, {billing_contact_zip}, {billing_contact_town}, {billing_contact_country}
* (analog für service_contact_* und delivery_contact_*)
*
* @param array $substitutionarray Referenz auf das Substitution-Array
* @param Translate $langs Sprachobjekt
* @param Object $object Dolibarr-Objekt (Facture, Propal, Commande)
*/
function deliveryinvoiceaddress_completesubstitutionarray(&$substitutionarray, $langs, $object)
{
global $conf, $db;
if (!is_object($object) || empty($object->id)) {
return;
}
// Element-Typ bestimmen (facture, propal, commande)
$elementType = $object->element ?? '';
if (empty($elementType)) {
return;
}
// Platzhalter-Prefixe je Kontakttyp
$codeToPrefix = array(
'BILLING' => 'billing_contact',
'CUSTOMER' => 'billing_contact', // Fallback für Angebote/Aufträge
'SERVICE' => 'service_contact',
'SHIPPING' => 'delivery_contact',
);
// Felder pro Kontakt
$fields = array('firstname', 'name', 'fullname', 'address', 'zip', 'town', 'country');
// Alle Platzhalter leer initialisieren
foreach (array('billing_contact', 'service_contact', 'delivery_contact') as $prefix) {
foreach ($fields as $field) {
$substitutionarray[$prefix.'_'.$field] = '';
}
}
// Kontaktdaten per JOIN direkt laden
$sql = "SELECT tc.code, sp.rowid, sp.firstname, sp.lastname, sp.address, sp.zip, sp.town,";
$sql .= " co.label as country";
$sql .= " FROM ".MAIN_DB_PREFIX."element_contact as ec";
$sql .= " JOIN ".MAIN_DB_PREFIX."c_type_contact as tc ON ec.fk_c_type_contact = tc.rowid";
$sql .= " JOIN ".MAIN_DB_PREFIX."socpeople as sp ON ec.fk_socpeople = sp.rowid";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON sp.fk_pays = co.rowid";
$sql .= " WHERE ec.element_id = ".((int) $object->id);
$sql .= " AND tc.element = '".$db->escape($elementType)."'";
$sql .= " AND tc.code IN ('BILLING', 'SERVICE', 'SHIPPING', 'CUSTOMER')";
$resql = $db->query($sql);
if (!$resql) {
dol_syslog("DeliveryInvoiceAddress: SQL FEHLER: ".$db->lasterror(), LOG_ERR);
return;
}
while ($obj = $db->fetch_object($resql)) {
$prefix = $codeToPrefix[$obj->code] ?? null;
if (!$prefix) {
continue;
}
// CUSTOMER nur als Fallback wenn BILLING noch leer
if ($obj->code == 'CUSTOMER' && !empty($substitutionarray['billing_contact_name'])) {
continue;
}
$firstname = $obj->firstname ?? '';
$lastname = $obj->lastname ?? '';
// Fullname: Vorname + Nachname, Reihenfolge je nach Dolibarr-Einstellung
$fullname = trim($firstname.' '.$lastname);
if (getDolGlobalString('MAIN_FIRSTNAME_NAME_POSITION')) {
$fullname = trim($lastname.' '.$firstname);
}
$substitutionarray[$prefix.'_firstname'] = $firstname;
$substitutionarray[$prefix.'_name'] = $lastname;
$substitutionarray[$prefix.'_fullname'] = $fullname;
$substitutionarray[$prefix.'_address'] = $obj->address ?? '';
$substitutionarray[$prefix.'_zip'] = $obj->zip ?? '';
$substitutionarray[$prefix.'_town'] = $obj->town ?? '';
$substitutionarray[$prefix.'_country'] = $obj->country ?? '';
}
$db->free($resql);
}