- 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>
95 lines
3.7 KiB
PHP
Executable file
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);
|
|
}
|