summaryrefslogtreecommitdiff
path: root/CLAUDE.md
blob: c94ecc290fcae8c52b38a633b13a02404d6906a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# Contact Package — Developer Notes

See also: `liberty/CLAUDE.md` for xref machinery underpinning this package.

## Person vs Business model

Two distinct contact types, entered via separate pages:
- `add_person.php` — auto-injects `$00` type; name stored pipe-separated
  (`prefix|forename|surname|suffix`) in `liberty_xref.xkey_ext` of the `$00` record;
  `lc.title` = surname; redirects to `edit.php` for further detail
- `add_business.php` — no `$00`; user picks from `$02`+ subtypes (Supplier, Manufacturer
  etc., expandable via DB); `lc.title` = organisation name; redirects to `edit.php`

Type codes in `liberty_xref_item` (`content_type_guid='contact'`, `x_group='type'`, `sort_order=0`):
- `$00` Person — triggers name fields in edit/display; never shown as a checkbox in UI
- `$01` Organisation — deprecated, not used in new UI
- `$02`+ Business subtypes — shown as checkboxes in `add_business.php` and `edit.php`

`edit.php` detects person via `contact_types[0].content_id` → `$isPerson` flag:
- Person: name fields shown, Contact Types section hidden, Organisation hidden
- Business: org field shown, Contact Types (`$02`+) shown, name fields hidden

`display_contact.tpl` heading = "Personal Contact" / "Business Contact" from `contact_types.0.content_id`.
Name loaded from `$00` xref `xkey_ext` via SQL join in `Contact::load()` (`x00.xkey_ext AS name`).

xref item templates gate dates and edit actions on `{$xrefAllowEdit}` (pass `allow_edit=false`
in view, `allow_edit=true` in edit).

**`contact_types`** — separate from the display path. Populated by `loadXrefTypeList()` which
queries sort_order=0 items (the 'type' group: `$00`, `$02`+). Used for `$isPerson` detection
in `edit.php` and display templates. `loadXrefInfo()` deliberately excludes sort_order=0,
so there is no overlap.

**SCREF** — short reference code for a contact, stored in `liberty_xref.xkey` where `item='SCREF'`.
Used as the `from` value in stock movement CSVs to identify the supplier/source contact.
`contact/includes/lookup_contact.php` provides JSON autocomplete searching by `lc.title` or SCREF `xkey`.

## Planned: ContactPerson / ContactBusiness subclasses

The current `$isPerson` detection via `$00` xref presence is a hack. The plan replaces it
with proper subclasses following the dual-guid xref pattern (as per stock):

- `ContactPerson extends Contact` — `mContentTypeGuid = 'contactperson'`, `mPackageGuid = 'contact'`
- `ContactBusiness extends Contact` — `mContentTypeGuid = 'contactbusiness'`, `mPackageGuid = 'contact'`

Shared schema (addresses, SCREF etc.) stays at `content_type_guid='contact'`.
Person-specific types (`$00` default, kitelf, committee member etc.) at `contactperson` level.
Business subtypes (`$02`+: Supplier, Manufacturer etc.) at `contactbusiness` level.
`$isPerson` flag disappears — the class IS the distinction.
Template resolution already works via `mContentTypeGuid` path lookup in LibertyContent.

**Not yet implemented.** Development/testing on `rainbowdigitalmedia` first.
Upgrade script `contact/admin/upgrades/5.0.3.php` will:
1. Register `contactperson` and `contactbusiness` content types
2. `UPDATE liberty_content SET content_type_guid = 'contactperson'` for records with a `$00` xref
3. Remaining `content_type_guid='contact'` records become `contactbusiness`

## Contact::load() — raw xref joins
Joins `liberty_xref` directly for `$00` (person name), `#S` (service address), `#L` (location),
`IMG` (gallery). `IMG`, `#S`, `#L` have no live data.

**Pending cleanup** — remove the three commented-out dead joins; replace active raw xref joins
with the proper path: `$00` name from `loadXrefTypeList()` with `xkey_ext` added;
`#S`/`#L`/`ap` from `loadXrefInfo()` address group (postcode join already present in
`LibertyXrefGroup::loadXrefs()`); gallery association needs rethinking separately.

## CSV import xorder
`ImportContactCSV.php` explicitly sets xorder: 0 for single items, 1 for #P/#F (multiple=1).
Will need addressing when more than one record is needed per xref group.

## Delete / expunge
`edit.php` handles `expunge=1`: checks `p_contact_expunge`, calls `$gContent->expunge()`,
redirects to `list_contacts.php`. `contact_date_bar.tpl` uses
`{smartlink ... ifile="edit.php" expunge=1}`. `Contact::expunge()` deletes liberty_xref rows
then calls `LibertyContent::expunge()`.