Record Marriage Data UK.fh_lua--[[
@Title: Record Marriage Data (UK)
@Type: Source-driven data entry
@Subtype: "Civil Registration Certificate", "Church Register"
@Author: Calico Pie
@Version: 1.4
@GH #11 #16 #25 #26 #30 #54 #76 #112 #119
@Keywords:
@LastUpdated: November 2021
@Description: Based on the format of the England and Wales Marriage Certificate/Parish Register since 1837, it allows creation of marriage, occupation and residence facts. It also supports creation of one or all of the records for the individuals involved. Only entry of details for the two principals is mandatory.
]]
fhInitialise(7)
fh = require 'fhUtils'
fh.setIupDefaults()
-- Local Globals
local form, templateName, templateDefault
local iForm = 1
local sPluginName = 'Marriage Certificate Entry'
local shortcuts = {} -- Autofill table
local pCite
local tUpdatedFields = {}
local cells = {}
--- Main process
function main()
--------------------------------------------------------------Load citation and associated fields
pCite = fh.loadPreparedCitation()
if not pCite.result then
fh.getParam(sPluginName, pCite.err)
return
end
-- Church Register uses EN-EVENT_TYPE but Civil Certificate uses EN-TYPE so copy values to Type field in Citation fields.
if not pCite.fields['EN-TYPE'] then
pCite.fields['EN-TYPE'] = pCite.fields['EN-EVENT_TYPE']
iForm = 2
end
if pCite:getValue 'EN-TYPE' ~= 'Marriage' then
fh.getParam(sPluginName, 'Only Marriage is supported by this plugin. ')
return
end
-- Ensure all needed fields have been completed
if
not (
pCite:checkRequired(
'EN-TYPE',
'NM-PRINCIPAL',
'NM-PRINCIPAL_2',
'DT-DATE'
)
)
then
fh.getParam(
sPluginName,
'Not all required fields are set,\nplease ensure you have entered date and both principals. '
)
return
end
-- Create form by copying master form to allow for resets
local masterForms = loadMasterForms()
form = tablex.deepcopy(masterForms[iForm]['sections'])
templateName = masterForms[iForm]['templateName']
templateDefault = masterForms[iForm]['templateDefault']
form.principal.fields[1].value = pCite:getValue 'NM-PRINCIPAL'
form.spouse.fields[1].value = pCite:getValue 'NM-PRINCIPAL_2'
dtEventDateString = pCite:getDisplayValue 'DT-DATE'
dtEventDate = pCite:getValue 'DT-DATE'
-- Get currently selected person
local ptrPrincipal = fh.getCurrentIndividual()
if
ptrPrincipal:IsNotNull() and fhGetItemText(ptrPrincipal, '~.SEX') == 'Male'
then
changePrincipal(ptrPrincipal, true)
end
-------------------------------------------------------------- Create Dialog
for k, v in pairs(form) do
grid = iup.gridbox {
numdiv = 2,
cgaplin = '1',
cgapcol = '1',
margin = '4x4',
expand = 'YES',
}
-- process all sections into grid
for l, f in ipairs(v.fields) do
if f.label then
local label = ' '
local value = ' '
if f.gridDisplay or v.gridDisplay then
label = f.label .. ':'
value = fh.getParamValueForDisplay(f, true)
end
f.gridLabel = iup.label { title = label, size = '80', expand = 'NO' }
iup.Append(grid, f.gridLabel)
f.iupgrid = iup.label { title = value, expand = 'YES' }
iup.Append(grid, f.iupgrid)
end
end
v.button = iup.button { title = 'Edit', active = 'NO' }
if v.editActive then
v.button.Active = 'YES'
end
v.button.action = function()
doEdit(k, v.title, v.seq)
end
cells[v.seq] = iup.vbox {
EXPANDCHILDREN = 'YES',
EXPAND = 'YES',
iup.frame {
title = v.title,
EXPANDCHILDREN = 'YES',
EXPAND = 'YES',
iup.vbox {
EXPANDCHILDREN = 'YES',
EXPAND = 'YES',
v.button,
grid,
},
},
}
end
-- Build Shortcut table
local placeList = fh.createPlaceList()
shortcuts['PLAC'] = placeList
shortcuts['OCCU'] = fhGetDataList 'OCCUPATIONS'
shortcuts['CONDITION'] = { 'Spinster', 'Bachelor', 'Widow', 'Widower' }
local addressList = {}
txtMessage = iup.label {
title = ' Hint: please edit the Principal section to enable the other sections',
}
btnOk = iup.button { title = 'OK', padding = '20x4', expand = 'HORIZONTAL' }
function btnOk.action()
if form.principal.valid and form.spouse.valid then
local sVenue = pCite:getValue 'TX-CHURCH'
if not sVenue then
sVenue = pCite:getValue 'AD-ADDRESS'
end
processMarriage(pCite:getValue 'PL-LOCATION', sVenue)
return iup.CLOSE
else
fhMessageBox 'Information has not been entered on both Principal and Spouse'
end
end
btnCancel =
iup.button { title = 'Cancel', padding = '4x4', expand = 'HORIZONTAL' }
function btnCancel.action()
return iup.CLOSE
end
local sTitle = 'Marriage Certificate Entry: '
.. fhGetDisplayText(pCite.source)
dlg = iup.dialog {
title = sTitle,
minsize = '1000',
iup.vbox {
EXPANDCHILDREN = 'YES',
EXPAND = 'YES',
iup.gridbox {
numdiv = 2,
cgaplin = '1',
cgapcol = '1',
margin = '4x4',
expand = 'YES',
EXPANDCHILDREN = 'YES',
table.unpack(cells),
},
iup.hbox {
margin = '4x4',
expand = 'NO',
btnOk,
btnCancel,
fh.helpButton 'record-marriage-data-uk',
txtMessage,
},
},
}
-- Set Dialog to have FH as a parent and prep any iup prebuilt componments to use the dialog.
iup.SetAttribute(dlg, 'NATIVEPARENT', fhGetContextInfo 'CI_PARENT_HWND') -- Set the parent window handle iup.SetHandle("main", dlg)
iup.SetGlobal('PARENTDIALOG', 'main')
-- present dialog
iup.Popup(dlg)
iup.Destroy(dlg)
end
-- --------------------------------------------------------------- doEdit
--- Called from the Edit buttons to update the sections
-- @param sType string, section name from form table
-- @param sTitle string Name of dialog
-- @param seq number, sequence number of section
function doEdit(sType, sTitle, seq)
local fields = form[sType].fields
local oldRecord = fhNewItemPtr()
if form[sType]['fields'][field(fields, 'RECORD')] then
oldRecord = form[sType]['fields'][field(fields, 'RECORD')].value:Clone()
end
if sType == 'principal' then
local oldFamily =
form[sType]['fields'][field(fields, 'FAMILY')].value:Clone()
local r = fh.getParam(
'Enter ' .. sTitle,
nil,
fields,
{ 'OK', 'Cancel', fh.helpButton 'record-marriage-data-uk-principal' },
shortcuts
)
if r.ok then
form[sType].valid = true
form[sType].gridDisplay = true
-- enable all Edit buttons
for k, v in pairs(form) do
v.button.Active = 'YES'
end
-- To Do Ripple all fields
if
not (oldRecord:IsSame(r.results['RECORD']))
or not (oldFamily:IsSame(r.results['FAMILY']))
then
changePrincipal(r.results['RECORD'])
end
end
else
local r = fh.getParam(
'Enter ' .. sTitle,
nil,
fields,
{ 'OK', 'Cancel' },
shortcuts
)
if r.ok then
form[sType].gridDisplay = true
form[sType].valid = true
if not (oldRecord:IsSame(r.results['RECORD'])) and sType == 'spouse' then
updateFatherSpouse(r.results['RECORD'])
end
end
end
updateGrid()
end
-- --------------------------------------------------------------- changePrincipal
--- Update other section/grid boxes when the Principal record is changed
-- @param ptrPrincipal fhItemPointer for the Principal person on the certifcate
-- @param init boolean, true on first run.
function changePrincipal(ptrPrincipal, init)
local f = form['principal'].fields
if ptrPrincipal:IsNotNull() then
f[field(f, 'RECORD')].value = ptrPrincipal
f[field(f, 'SEX')].value = fhGetItemText(ptrPrincipal, '~.SEX')
-- f[field(f,'SEX')].protect = true
if init then
-- first time load or new Record selected
local values, prompts = updateFamList(ptrPrincipal, 'FamilyAsSpouse')
f[field(f, 'FAMILY')].values = values
f[field(f, 'FAMILY')].prompts = prompts
f[field(f, 'FAMILY')].value = values[1]
f[field(f, 'ACTION')].value = 'select'
f[field(f, 'FAMILY')].protect = false
f[field(f, 'RECORD')].protect = false
end
-- Set up Father of Principal if they exist
local ptrF = fhGetItemPtr(ptrPrincipal, '~.~FATH>')
if ptrF:IsNotNull() then
local s = form['fatherPrincipal'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrF:Clone()
s[field(s, 'RECORD')].protect = false
s[field(s, 'ACTION')].value = 'select'
end
if f[field(f, 'FAMILY')].value:IsNotNull() then
-- Have Family As Spouse Get Spouse
local s = form['spouse'].fields
local ptrFam = f[field(f, 'FAMILY')].value or fhNewItemPtr()
local ptrS = fhGetItemPtr(ptrFam, '~.WIFE>')
if ptrS:IsSame(ptrPrincipal) then
ptrS = fhGetItemPtr(ptrFam, '~.HUSB>')
end
if ptrS:IsNotNull() then
s[field(s, 'RECORD')].value = ptrS
s[field(s, 'SEX')].value = fhGetItemText(ptrS, '~.SEX')
s[field(s, 'SEX')].protect = true
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'RECORD')].protect = true
s[field(s, 'ACTION')].protect = true
-- Set up Father as Spouse
local ptrSF = fhGetItemPtr(ptrS, '~.~FATH>')
if ptrSF:IsNotNull() then
local s = form['fatherSpouse'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrSF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrSF:Clone()
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'RECORD')].protect = false
else
resetSection 'fatherSpouse'
end
else
-- No Spouse
resetSection 'spouse'
resetSection 'fatherSpouse'
end
else
-- No Family As Spouse
resetSection 'spouse'
resetSection 'fatherSpouse'
end
else
resetSection 'spouse'
resetSection 'fatherSpouse'
resetSection 'fatherPrincipal'
end
end
-- --------------------------------------------------------------- updateFatherSpouse
--- update the Father of the Spouse when the spouse is changed
-- @param ptrS fhItemPointer for the Spouse Record
function updateFatherSpouse(ptrS)
-- Set up Father as Spouse
local ptrSF = fhGetItemPtr(ptrS, '~.~FATH>')
if ptrSF:IsNotNull() then
local s = form['fatherSpouse'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrSF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrSF:Clone()
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'RECORD')].protect = false
else
resetSection 'fatherSpouse'
end
end
-- --------------------------------------------------------------- resetSection
--- Reset the section values from the master form
-- @param formSection string section index
function resetSection(formSection)
for k, v in ipairs(masterForms[iForm].sections[formSection].fields) do
for m, u in pairs(v) do
form[formSection]['fields'][k][m] = u
end
end
end
-- --------------------------------------------------------------- updateGrid
--- Update All Grid Fields from table
function updateGrid()
for sType, sSection in pairs(form) do
for l, f in ipairs(sSection.fields) do
local label = ' '
local value = ' '
if f.gridDisplay or form[sType].gridDisplay then
label = f.label
value = fh.getParamValueForDisplay(f, true)
end
if f.gridLabel then
f.gridLabel.title = label
end
if f.iupgrid then
f.iupgrid.title = value
end
end
end
end
-- --------------------------------------------------------------- processMarriage
--- record all marriage information from form to gedcom
-- @param sPlace string, place of marriage
-- @param sAddress string, address/venue of marriage
-- ~param sCelebrant string
function processMarriage(sPlace, sAddress, sCelebrant)
local data = {}
for k, s in pairs(form) do
data[k] = {}
for i, f in ipairs(s.fields) do
data[k][f.tag] = { value = f.value, type = f.type, dr = f.df }
end
end
-- Create needed Individual Records
for _, f in pairs(data) do
if f.ACTION and f.ACTION.value == 'create' then
local sex
if f.SEX and f.SEX.value then
sex = f.SEX.value
end
local ptr = fh.createIndi(f.NAME.value, sex)
addCitation(ptr, 'Created')
-- #16 Cite Name
local ptrName = fhGetItemPtr(ptr, '~.NAME')
addCitation(ptrName, 'Cited')
f.RECORD.value:MoveTo(ptr)
end
end
-- Create Family Record if needed
if data.principal.FAMILY.value:IsNull() then
ptrFam = fh.createFamilyAsSpouse(data.principal.RECORD.value)
addCitation(ptrFam, 'Created')
data.principal.FAMILY.value:MoveTo(ptrFam)
fh.addFamilyAsSpouse(data.spouse.RECORD.value, ptrFam)
data.principal.FAMILY.value:MoveTo(ptrFam)
end
if
fhGetItemPtr(data.principal.FAMILY.value, '~.HUSB>'):IsNull()
or fhGetItemPtr(data.principal.FAMILY.value, '~.WIFE>'):IsNull()
then
fh.addFamilyAsSpouse(data.spouse.RECORD.value, data.principal.FAMILY.value)
addCitation(data.principal.FAMILY.value, 'Updated')
end
-- Process Fathers
if data.fatherPrincipal.ACTION.value ~= 'name' then
processParent(
data.fatherPrincipal.RECORD.value,
data.principal.RECORD.value
)
end
if data.fatherSpouse.ACTION.value ~= 'name' then
processParent(data.fatherSpouse.RECORD.value, data.spouse.RECORD.value)
end
local eventDate = pCite:getValue 'DT-DATE'
-- Create / Update Marriage Event
local ptrMARR = fhGetItemPtr(data.principal.FAMILY.value, '~.MARR')
local sAction = 'Added'
if ptrMARR:IsNotNull() then
ptrMARR, sAction = fh.createUpdateFact(
data.principal.FAMILY.value,
'MARR',
'Marriage',
sPlace,
eventDate,
sAddress
)
else
ptrMARR = fh.createFact(
data.principal.FAMILY.value,
'MARR',
sPlace,
eventDate,
sAddress
)
end
if ptrMARR and ptrMARR:IsNotNull() then
local sPrincipal = 'HUSB'
local sSpouse = 'WIFE'
if data.principal.SEX.value == 'Female' then
local sPrincipal = 'WIFE'
local sSpouse = 'HUSB'
end
-- Add Ages
if data.principal.AGE then
local age = data.principal.AGE.value
if age:sub(1, 1) == 'f' or age:sub(1, 1) == 'F' then
age = '> 21'
end
local l = fhCreateItem(sPrincipal, ptrMARR)
local a = fhCreateItem('AGE', l, true)
local res = fhSetValueAsText(a, age)
end
if data.spouse.AGE then
local age = data.spouse.AGE.value
if age:sub(1, 1) == 'f' or age:sub(1, 1) == 'F' then
age = '> 21'
end
local l = fhCreateItem(sSpouse, ptrMARR)
local a = fhCreateItem('AGE', l, true)
res = fhSetValueAsText(a, age)
end
addCitation(ptrMARR, sAction)
end
for k, f in pairs(data) do
if f.RECORD and f.RECORD.value:IsNotNull() then
if f.OCCU and f.OCCU.value:len() > 0 then
local ptrFact
if k == 'principal' or k == 'spouse' then
-- 3/8/20 Remove place and address from Occupation
ptrFact = fh.createFact(
f.RECORD.value,
'OCCU',
nil,
eventDate,
nill,
f.OCCU.value,
f.AGE.value
)
else
if f.DECEASED and f.DECEASED.value then
ptrFact = fh.createFact(
f.RECORD.value,
'OCCU',
nil,
beforeDate(eventDate),
nil,
f.OCCU.value
)
else
ptrFact = fh.createFact(
f.RECORD.value,
'OCCU',
nil,
eventDate,
nil,
f.OCCU.value
)
end
end
if ptrFact then
addCitation(ptrFact, 'Added')
end
end
if f.DECEASED and f.DECEASED.value then
local ptrFact = fhGetItemPtr(f.RECORD.value, '~.DEAT')
local sAction
if ptrFact:IsNull() then
ptrFact = fh.createFact(
f.RECORD.value,
'DEAT',
nil,
beforeDate(eventDate)
)
if ptrFact then
addCitation(ptrFact, 'Added')
end
else
ptrFact, sAction = fh.createUpdateFact(
f.RECORD.value,
'DEAT',
'Death',
nil,
beforeDate(eventDate)
)
if ptrFact then
addCitation(ptrFact, sAction)
end
end
end
local dtBirth
if f.AGE then
local age = string.lower(f.AGE.value)
if age:sub(1, 1) == 'f' then
age = '21'
dtBirth = fh.calcBirth(eventDate, age)
dtBirth:SetRange('before', dtBirth:GetDatePt1())
else
dtBirth = fh.calcBirth(eventDate, f.AGE.value)
end
local ptrFact = fhGetItemPtr(f.RECORD.value, '~.BIRT')
ptrFact, sAction = fh.createUpdateFact(
f.RECORD.value,
'BIRT',
'Birth',
nil,
dtBirth
)
if ptrFact then
addCitation(ptrFact, sAction)
end
end
if f.PLAC and f.PLAC.value:len() > 0 then
local ptrFact, sAction = fh.createFact(
f.RECORD.value,
'RESI',
f.PLAC.value,
eventDate,
f.ADDR.value,
nil,
f.AGE.value
)
if ptrFact then
addCitation(ptrFact, 'Added')
end
end
if ptrMARR and f.WITNESS then
if f.ACTION.value == 'name' and fh.isSet(f.NAME.value) then
fh.addWitness(ptrMARR, f.NAME.value, 'Witness')
elseif fh.isSet(f.RECORD.value) then
fh.addWitness(ptrMARR, f.RECORD.value, 'Witness')
end
end
end
if f.ROLE and f.ROLE.value and f.CELEBRANT.value ~= '' then
-- Create Role for Celebrant in Marriage
fh.addWitness(ptrMARR, f.CELEBRANT.value, f.ROLE.value)
end
end
-- Output Text From Source
local fields = {}
for k, s in pairs(form) do
for i, f in ipairs(s.fields) do
local inx = string.upper(k .. '.' .. tostring(f.tag))
fields[inx] = fh.getParamValueForDisplay(f)
if f.tag == 'NAME' and data[k].RECORD then
local ptr = data[k].RECORD.value
if ptr:IsNotNull() then
-- Add record link
fields[inx] = fh.richTextRecordLink(ptr, fields[inx])
end
end
end
end
if not (pCite:checkRequired 'AD-ADDRESS') then
fields['AD-ADDRESS'] = ''
end
if not (pCite:checkRequired 'TX-CHURCH') then
fields['TX-CHURCH'] = ''
end
sText = fh.formatTextFromSource(templateName, templateDefault, pCite, fields)
ptrTextFromSource = fh.createTextFromSource(pCite, sText, 'source')
-- Output Final Result Set and Close.
fh.outputUpdatedFields(tUpdatedFields, pCite)
end
-- --------------------------------------------------------------- beforeDate
--- Add "before" to a date
-- @param dt fhDate
-- @return fhDate
function beforeDate(dt)
local newDate = fhNewDate()
if dt:IsNull() then
return
end
dp = dt:GetDatePt1()
if dp:IsNull() then
return
end
newDate:SetRange('before', dp)
return newDate
end
-- --------------------------------------------------------------- addCitation
--- add the current citation to an item and add it the output list
-- @param ptr fhItemPointer
-- @param action string value to output to the result set
function addCitation(ptr, action)
local action = action or ''
table.insert(tUpdatedFields, { ptr:Clone(), action })
pCite:appendCitation(ptr)
end
-- --------------------------------------------------------------- processParent
--- Check and add Parents as needed to a child
-- @param ptrParent Parent Record Pointer
-- @param ptrChild Child Record Pointer
function processParent(ptrParent, ptrChild)
local parentSex = fhGetItemText(ptrParent, 'SEX')
local ptrFamC = fhNewItemPtr()
local ptrHusb = fhNewItemPtr()
local ptrWife = fhNewItemPtr()
local bNewFam = true
ptrFamC:MoveTo(ptrChild, '~.FAMC')
while ptrFamC:IsNotNull() do
ptrHusb:MoveTo(ptrFamC, '~>HUSB>')
ptrWife:MoveTo(ptrFamC, '~>WIFE>')
if ptrHusb:IsSame(ptrParent) or ptrWife:IsSame(ptrParent) then
bNewFam = false
end
ptrFamC:MoveNext 'SAME_TAG'
end
if bNewFam then
ptrFam = fh.createFamilyAsChild(ptrChild)
fh.addFamilyAsSpouse(ptrParent, ptrFam)
addCitation(ptrFam, 'Created')
end
end
-- --------------------------------------------------------------- selectOrCreate
--- ChildUpdate handler
-- @param value string - value of list box
-- @return boolean - true if value select
function selectOrCreate(value)
if value == 'select' then
return false, 1
else
return true, 0
end
end
-- --------------------------------------------------------------- updateFamList
--- Updates Prompts for the Family list on the principle.
-- @param ptr Principles pointer
-- @return table fhItemPointer, family list pointers
-- @return table string,family list descriptions
function updateFamList(ptr, fields)
local ptrs = {}
local prompts = {}
local famList = fh.familyList(ptr, 'FamilyAsSpouse')
for i, tFam in ipairs(famList) do
table.insert(ptrs, tFam.ptr)
table.insert(prompts, tFam.label)
end
-- Set Sex Field
if ptr:IsNotNull() and fields and fields[5] and fields[5].iupcontrol then
local sSex = fhGetItemText(ptr, '~.SEX')
if sSex == 'Male' then
fields[5].iupcontrol.value = 1
else
fields[5].iupcontrol.value = 2
end
end
return ptrs, prompts
end
-- --------------------------------------------------------------- field
--- get the field index from the tag
-- @param fields table of fields
-- @param tag string value of field tag
-- @return integer number of field in fields list
function field(fields, tag)
local i
for i, v in ipairs(fields) do
if tag == v.tag then
return i
end
end
end
-- --------------------------------------------------------------- address
--- getParam helper returns list of addresses for place
-- @param place string, place name
-- @return table of matching addresses
function address(place)
local addr = fh.createAddressList(place)
return addr
end
function loadMasterForms()
ptrFamily = fhNewItemPtr()
masterForms = {}
masterForms[1] = {
templateName = 'Marriage Certificate (UK).ftf',
templateDefault = [[Marriage of {NM-PRINCIPAL} and {NM-PRINCIPAL_2}
Certified Copy of an entry of Marriage
Registration District {ADDITIONAL.DISTRICT}
Place | Venue | Celebrant | Type | Reference
{PL-LOCATION} | {TX-CHURCH} {AD-ADDRESS} | {ADDITIONAL.CELEBRANT} {ADDITIONAL.ROLE} | {ADDITIONAL.TYPE} |{TX-REFERENCE}
When Married | Name and Surname | Age | Condition | Rank or Profession | Residence at time of Marriage | Fathers Name | Fathers Occupation
{DT-DATE} | {PRINCIPAL.NAME} | {PRINCIPAL.AGE} | {PRINCIPAL.CONDITION} | {PRINCIPAL.OCCU} | {PRINCIPAL.ADDR}
{PRINCIPAL.PLAC} | {FATHERPRINCIPAL.NAME} | {FATHERPRINCIPAL.OCCU}
{FATHERPRINCIPAL.DECEASED}
| {SPOUSE.NAME} | {SPOUSE.AGE} | {SPOUSE.CONDITION} | {SPOUSE.OCCU} | {SPOUSE.ADDR}
{SPOUSE.PLAC} | {FATHERSPOUSE.NAME} | {FATHERSPOUSE.OCCU}
{FATHERSPOUSE.DECEASED}
Witnessed by {WITNESS1.NAME} , {WITNESS2.NAME}
Reference {TX-REFERENCE}
]],
sections = {
principal = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = pCite:getValue 'NM-PRINCIPAL',
minlength = 1,
protect = true,
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add principal as',
type = 'LIST',
value = 'create',
values = { 'create', 'select' },
prompts = { 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = function(...)
return selectOrCreate(...)
end,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
dr = 'PTR',
value = fhNewItemPtr(),
protect = true,
child = 'FAMILY',
childUpdate = function(...)
return updateFamList(...)
end,
},
{
tag = 'FAMILY',
label = 'Family',
type = 'LIST',
value = ptrFamily,
values = { ptrFamily },
prompts = { 'New Family as Spouse' },
},
{
tag = 'SEX',
type = 'LIST',
label = 'Sex',
dr = 'SEX',
value = 'Male',
values = { 'Male', 'Female', 'Unknown' },
},
{
tag = 'AGE',
type = 'STRING',
label = 'Age (or full)',
dr = 'AGE',
value = '',
mask = '(/d+[dwmyf]|full|Full)',
minlength = 1,
},
{
tag = 'CONDITION',
type = 'STRING',
label = 'Condition',
value = '',
minlength = 1,
},
{ tag = 'OCCU', dr = 'OCCU', type = 'STRING', label = 'Occupation', value = '' },
{
tag = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = address,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
{ tag = 'BIRT', dr = 'BIRT' },
},
title = 'Principal',
label = 'principal',
seq = 1,
editActive = true,
gridDisplay = true,
},
fatherPrincipal = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add father as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = { 'Name Only', 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{ tag = 'OCCU', dr = 'OCCU', type = 'STRING', label = 'Occupation', value = '' },
{ tag = 'DECEASED', type = 'BOOLEAN', label = 'Deceased', value = false },
{ tag = 'SEX', value = 'Male' },
},
title = 'Father of principal',
seq = 2,
gridDisplay = false,
},
spouse = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = pCite:getValue 'NM-PRINCIPAL_2',
minlength = 1,
protect = true,
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add spouse as',
type = 'LIST',
value = 'create',
values = { 'create', 'select' },
prompts = { 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
protect = false,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{
tag = 'SEX',
type = 'LIST',
label = 'Sex',
dr = 'SEX',
value = 'Female',
values = { 'Male', 'Female', 'Unknown' },
},
{
tag = 'AGE',
type = 'STRING',
label = 'Age (or full)',
dr = 'AGE',
value = '',
mask = '(/d+[dwmyf]|full|Full)',
minlength = 1,
},
{
tag = 'CONDITION',
type = 'STRING',
label = 'Condition',
value = '',
minlength = 1,
},
{ tag = 'OCCU', dr = 'OCCU', type = 'STRING', label = 'Occupation', value = '' },
{
tag = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = address,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
{ tag = 'BIRT', dr = 'BIRT' },
},
title = 'Spouse',
seq = 3,
gridDisplay = false,
},
fatherSpouse = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add Father as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = { 'Name Only', 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{ tag = 'OCCU', dr = 'OCCU', type = 'STRING', label = 'Occupation', value = '' },
{ tag = 'DECEASED', type = 'BOOLEAN', label = 'Deceased', value = false },
{ tag = 'SEX', value = 'Male' },
},
title = 'Father of Spouse',
seq = 4,
gridDisplay = false,
},
witness1 = {
fields = {
{
tag = 'NAME',
label = 'Witness Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
},
{
tag = 'ACTION',
label = 'Add witness as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = { 'Name only', 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{ tag = 'WITNESS', dr = 'SHA' },
},
title = 'Witness 1',
seq = 5,
gridDisplay = false,
},
witness2 = {
fields = {
{
tag = 'NAME',
label = 'Witness Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
},
{
tag = 'ACTION',
label = 'Add witness as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = { 'Name only', 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{ tag = 'WITNESS', dr = 'SHA' },
},
title = 'Witness 2',
seq = 6,
gridDisplay = false,
},
additional = {
fields = {
{
tag = 'CELEBRANT',
label = 'Celebrant',
type = 'STRING',
dr = 'NAME',
value = '',
},
{
tag = 'ROLE',
label = 'Role',
type = 'LIST',
value = 'None',
values = { 'None', 'Minister', 'Registrar' },
},
{
tag = 'TYPE',
label = 'Marriage Type',
type = 'LIST',
value = '',
values = {
'',
'By Banns',
'After Banns',
'By Licence',
'By Certificate',
},
},
{
tag = 'DISTRICT',
label = 'Registration District',
type = 'STRING',
dr = 'NAME',
value = '',
},
},
title = 'Additional Information',
seq = 7,
gridDisplay = false,
},
},
}
-- Set up Parish Varient
masterForms[2] = tablex.deepcopy(masterForms[1])
masterForms[2].templateName = 'Church Marriage (UK).ftf'
masterForms[2].templateDefault =
[[Marriage of {NM-PRINCIPAL} and {NM-PRINCIPAL_2}
Place | Church | Celebrant | Type | Reference
{PL-LOCATION} | {TX-CHURCH} {AD-ADDRESS} | {ADDITIONAL.CELEBRANT} {ADDITIONAL.ROLE} | {ADDITIONAL.TYPE} |{TX-REFERENCE}
When Married | Name and Surname | Age | Condition | Rank or Profession | Residence at time of Marriage | Fathers Name | Fathers Occupation
{DT-DATE} | {PRINCIPAL.NAME} | {PRINCIPAL.AGE} | {PRINCIPAL.CONDITION} | {PRINCIPAL.OCCU} | {PRINCIPAL.ADDR}
{PRINCIPAL.PLAC} | {FATHERPRINCIPAL.NAME} | {FATHERPRINCIPAL.OCCU}
{FATHERPRINCIPAL.DECEASED}
| {SPOUSE.NAME} | {SPOUSE.AGE} | {SPOUSE.CONDITION} | {SPOUSE.OCCU} | {SPOUSE.ADDR}
{SPOUSE.PLAC} | {FATHERSPOUSE.NAME} | {FATHERSPOUSE.OCCU}
{FATHERSPOUSE.DECEASED}
Witnessed by {WITNESS1.NAME} , {WITNESS2.NAME}
Reference {TX-REFERENCE}
]]
-- Remove Civil Information fields.
-- TODO
masterForms[2].sections.additional.fields[4] = nil
return masterForms
end
-------------------------------------------------------------------------------------------------------- Start Plugin
main()
--[[
@Title: Record Marriage Data (UK)
@Type: Source-driven data entry
@Subtype: "Civil Registration Certificate", "Church Register"
@Author: Calico Pie
@Version: 1.4
@GH #11 #16 #25 #26 #30 #54 #76 #112 #119
@Keywords:
@LastUpdated: November 2021
@Description: Based on the format of the England and Wales Marriage Certificate/Parish Register since 1837, it allows creation of marriage, occupation and residence facts. It also supports creation of one or all of the records for the individuals involved. Only entry of details for the two principals is mandatory.
]]
fhInitialise(7)
fh = require 'fhUtils'
fh.setIupDefaults()
-- Local Globals
local form, templateName, templateDefault
local iForm = 1
local sPluginName = 'Marriage Certificate Entry'
local shortcuts = {} -- Autofill table
local pCite
local tUpdatedFields = {}
local cells = {}
--- Main process
function main()
--------------------------------------------------------------Load citation and associated fields
pCite = fh.loadPreparedCitation()
if not pCite.result then
fh.getParam(sPluginName, pCite.err)
return
end
-- Church Register uses EN-EVENT_TYPE but Civil Certificate uses EN-TYPE so copy values to Type field in Citation fields.
if not pCite.fields['EN-TYPE'] then
pCite.fields['EN-TYPE'] = pCite.fields['EN-EVENT_TYPE']
iForm = 2
end
if pCite:getValue 'EN-TYPE' ~= 'Marriage' then
fh.getParam(sPluginName, 'Only Marriage is supported by this plugin. ')
return
end
-- Ensure all needed fields have been completed
if
not (
pCite:checkRequired(
'EN-TYPE',
'NM-PRINCIPAL',
'NM-PRINCIPAL_2',
'DT-DATE'
)
)
then
fh.getParam(
sPluginName,
'Not all required fields are set,\nplease ensure you have entered date and both principals. '
)
return
end
-- Create form by copying master form to allow for resets
local masterForms = loadMasterForms()
form = tablex.deepcopy(masterForms[iForm]['sections'])
templateName = masterForms[iForm]['templateName']
templateDefault = masterForms[iForm]['templateDefault']
form.principal.fields[1].value = pCite:getValue 'NM-PRINCIPAL'
form.spouse.fields[1].value = pCite:getValue 'NM-PRINCIPAL_2'
dtEventDateString = pCite:getDisplayValue 'DT-DATE'
dtEventDate = pCite:getValue 'DT-DATE'
-- Get currently selected person
local ptrPrincipal = fh.getCurrentIndividual()
if
ptrPrincipal:IsNotNull() and fhGetItemText(ptrPrincipal, '~.SEX') == 'Male'
then
changePrincipal(ptrPrincipal, true)
end
-------------------------------------------------------------- Create Dialog
for k, v in pairs(form) do
grid = iup.gridbox {
numdiv = 2,
cgaplin = '1',
cgapcol = '1',
margin = '4x4',
expand = 'YES',
}
-- process all sections into grid
for l, f in ipairs(v.fields) do
if f.label then
local label = ' '
local value = ' '
if f.gridDisplay or v.gridDisplay then
label = f.label .. ':'
value = fh.getParamValueForDisplay(f, true)
end
f.gridLabel = iup.label { title = label, size = '80', expand = 'NO' }
iup.Append(grid, f.gridLabel)
f.iupgrid = iup.label { title = value, expand = 'YES' }
iup.Append(grid, f.iupgrid)
end
end
v.button = iup.button { title = 'Edit', active = 'NO' }
if v.editActive then
v.button.Active = 'YES'
end
v.button.action = function()
doEdit(k, v.title, v.seq)
end
cells[v.seq] = iup.vbox {
EXPANDCHILDREN = 'YES',
EXPAND = 'YES',
iup.frame {
title = v.title,
EXPANDCHILDREN = 'YES',
EXPAND = 'YES',
iup.vbox {
EXPANDCHILDREN = 'YES',
EXPAND = 'YES',
v.button,
grid,
},
},
}
end
-- Build Shortcut table
local placeList = fh.createPlaceList()
shortcuts['PLAC'] = placeList
shortcuts['OCCU'] = fhGetDataList 'OCCUPATIONS'
shortcuts['CONDITION'] = { 'Spinster', 'Bachelor', 'Widow', 'Widower' }
local addressList = {}
txtMessage = iup.label {
title = ' Hint: please edit the Principal section to enable the other sections',
}
btnOk = iup.button { title = 'OK', padding = '20x4', expand = 'HORIZONTAL' }
function btnOk.action()
if form.principal.valid and form.spouse.valid then
local sVenue = pCite:getValue 'TX-CHURCH'
if not sVenue then
sVenue = pCite:getValue 'AD-ADDRESS'
end
processMarriage(pCite:getValue 'PL-LOCATION', sVenue)
return iup.CLOSE
else
fhMessageBox 'Information has not been entered on both Principal and Spouse'
end
end
btnCancel =
iup.button { title = 'Cancel', padding = '4x4', expand = 'HORIZONTAL' }
function btnCancel.action()
return iup.CLOSE
end
local sTitle = 'Marriage Certificate Entry: '
.. fhGetDisplayText(pCite.source)
dlg = iup.dialog {
title = sTitle,
minsize = '1000',
iup.vbox {
EXPANDCHILDREN = 'YES',
EXPAND = 'YES',
iup.gridbox {
numdiv = 2,
cgaplin = '1',
cgapcol = '1',
margin = '4x4',
expand = 'YES',
EXPANDCHILDREN = 'YES',
table.unpack(cells),
},
iup.hbox {
margin = '4x4',
expand = 'NO',
btnOk,
btnCancel,
fh.helpButton 'record-marriage-data-uk',
txtMessage,
},
},
}
-- Set Dialog to have FH as a parent and prep any iup prebuilt componments to use the dialog.
iup.SetAttribute(dlg, 'NATIVEPARENT', fhGetContextInfo 'CI_PARENT_HWND') -- Set the parent window handle iup.SetHandle("main", dlg)
iup.SetGlobal('PARENTDIALOG', 'main')
-- present dialog
iup.Popup(dlg)
iup.Destroy(dlg)
end
-- --------------------------------------------------------------- doEdit
--- Called from the Edit buttons to update the sections
-- @param sType string, section name from form table
-- @param sTitle string Name of dialog
-- @param seq number, sequence number of section
function doEdit(sType, sTitle, seq)
local fields = form[sType].fields
local oldRecord = fhNewItemPtr()
if form[sType]['fields'][field(fields, 'RECORD')] then
oldRecord = form[sType]['fields'][field(fields, 'RECORD')].value:Clone()
end
if sType == 'principal' then
local oldFamily =
form[sType]['fields'][field(fields, 'FAMILY')].value:Clone()
local r = fh.getParam(
'Enter ' .. sTitle,
nil,
fields,
{ 'OK', 'Cancel', fh.helpButton 'record-marriage-data-uk-principal' },
shortcuts
)
if r.ok then
form[sType].valid = true
form[sType].gridDisplay = true
-- enable all Edit buttons
for k, v in pairs(form) do
v.button.Active = 'YES'
end
-- To Do Ripple all fields
if
not (oldRecord:IsSame(r.results['RECORD']))
or not (oldFamily:IsSame(r.results['FAMILY']))
then
changePrincipal(r.results['RECORD'])
end
end
else
local r = fh.getParam(
'Enter ' .. sTitle,
nil,
fields,
{ 'OK', 'Cancel' },
shortcuts
)
if r.ok then
form[sType].gridDisplay = true
form[sType].valid = true
if not (oldRecord:IsSame(r.results['RECORD'])) and sType == 'spouse' then
updateFatherSpouse(r.results['RECORD'])
end
end
end
updateGrid()
end
-- --------------------------------------------------------------- changePrincipal
--- Update other section/grid boxes when the Principal record is changed
-- @param ptrPrincipal fhItemPointer for the Principal person on the certifcate
-- @param init boolean, true on first run.
function changePrincipal(ptrPrincipal, init)
local f = form['principal'].fields
if ptrPrincipal:IsNotNull() then
f[field(f, 'RECORD')].value = ptrPrincipal
f[field(f, 'SEX')].value = fhGetItemText(ptrPrincipal, '~.SEX')
-- f[field(f,'SEX')].protect = true
if init then
-- first time load or new Record selected
local values, prompts = updateFamList(ptrPrincipal, 'FamilyAsSpouse')
f[field(f, 'FAMILY')].values = values
f[field(f, 'FAMILY')].prompts = prompts
f[field(f, 'FAMILY')].value = values[1]
f[field(f, 'ACTION')].value = 'select'
f[field(f, 'FAMILY')].protect = false
f[field(f, 'RECORD')].protect = false
end
-- Set up Father of Principal if they exist
local ptrF = fhGetItemPtr(ptrPrincipal, '~.~FATH>')
if ptrF:IsNotNull() then
local s = form['fatherPrincipal'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrF:Clone()
s[field(s, 'RECORD')].protect = false
s[field(s, 'ACTION')].value = 'select'
end
if f[field(f, 'FAMILY')].value:IsNotNull() then
-- Have Family As Spouse Get Spouse
local s = form['spouse'].fields
local ptrFam = f[field(f, 'FAMILY')].value or fhNewItemPtr()
local ptrS = fhGetItemPtr(ptrFam, '~.WIFE>')
if ptrS:IsSame(ptrPrincipal) then
ptrS = fhGetItemPtr(ptrFam, '~.HUSB>')
end
if ptrS:IsNotNull() then
s[field(s, 'RECORD')].value = ptrS
s[field(s, 'SEX')].value = fhGetItemText(ptrS, '~.SEX')
s[field(s, 'SEX')].protect = true
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'RECORD')].protect = true
s[field(s, 'ACTION')].protect = true
-- Set up Father as Spouse
local ptrSF = fhGetItemPtr(ptrS, '~.~FATH>')
if ptrSF:IsNotNull() then
local s = form['fatherSpouse'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrSF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrSF:Clone()
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'RECORD')].protect = false
else
resetSection 'fatherSpouse'
end
else
-- No Spouse
resetSection 'spouse'
resetSection 'fatherSpouse'
end
else
-- No Family As Spouse
resetSection 'spouse'
resetSection 'fatherSpouse'
end
else
resetSection 'spouse'
resetSection 'fatherSpouse'
resetSection 'fatherPrincipal'
end
end
-- --------------------------------------------------------------- updateFatherSpouse
--- update the Father of the Spouse when the spouse is changed
-- @param ptrS fhItemPointer for the Spouse Record
function updateFatherSpouse(ptrS)
-- Set up Father as Spouse
local ptrSF = fhGetItemPtr(ptrS, '~.~FATH>')
if ptrSF:IsNotNull() then
local s = form['fatherSpouse'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrSF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrSF:Clone()
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'RECORD')].protect = false
else
resetSection 'fatherSpouse'
end
end
-- --------------------------------------------------------------- resetSection
--- Reset the section values from the master form
-- @param formSection string section index
function resetSection(formSection)
for k, v in ipairs(masterForms[iForm].sections[formSection].fields) do
for m, u in pairs(v) do
form[formSection]['fields'][k][m] = u
end
end
end
-- --------------------------------------------------------------- updateGrid
--- Update All Grid Fields from table
function updateGrid()
for sType, sSection in pairs(form) do
for l, f in ipairs(sSection.fields) do
local label = ' '
local value = ' '
if f.gridDisplay or form[sType].gridDisplay then
label = f.label
value = fh.getParamValueForDisplay(f, true)
end
if f.gridLabel then
f.gridLabel.title = label
end
if f.iupgrid then
f.iupgrid.title = value
end
end
end
end
-- --------------------------------------------------------------- processMarriage
--- record all marriage information from form to gedcom
-- @param sPlace string, place of marriage
-- @param sAddress string, address/venue of marriage
-- ~param sCelebrant string
function processMarriage(sPlace, sAddress, sCelebrant)
local data = {}
for k, s in pairs(form) do
data[k] = {}
for i, f in ipairs(s.fields) do
data[k][f.tag] = { value = f.value, type = f.type, dr = f.df }
end
end
-- Create needed Individual Records
for _, f in pairs(data) do
if f.ACTION and f.ACTION.value == 'create' then
local sex
if f.SEX and f.SEX.value then
sex = f.SEX.value
end
local ptr = fh.createIndi(f.NAME.value, sex)
addCitation(ptr, 'Created')
-- #16 Cite Name
local ptrName = fhGetItemPtr(ptr, '~.NAME')
addCitation(ptrName, 'Cited')
f.RECORD.value:MoveTo(ptr)
end
end
-- Create Family Record if needed
if data.principal.FAMILY.value:IsNull() then
ptrFam = fh.createFamilyAsSpouse(data.principal.RECORD.value)
addCitation(ptrFam, 'Created')
data.principal.FAMILY.value:MoveTo(ptrFam)
fh.addFamilyAsSpouse(data.spouse.RECORD.value, ptrFam)
data.principal.FAMILY.value:MoveTo(ptrFam)
end
if
fhGetItemPtr(data.principal.FAMILY.value, '~.HUSB>'):IsNull()
or fhGetItemPtr(data.principal.FAMILY.value, '~.WIFE>'):IsNull()
then
fh.addFamilyAsSpouse(data.spouse.RECORD.value, data.principal.FAMILY.value)
addCitation(data.principal.FAMILY.value, 'Updated')
end
-- Process Fathers
if data.fatherPrincipal.ACTION.value ~= 'name' then
processParent(
data.fatherPrincipal.RECORD.value,
data.principal.RECORD.value
)
end
if data.fatherSpouse.ACTION.value ~= 'name' then
processParent(data.fatherSpouse.RECORD.value, data.spouse.RECORD.value)
end
local eventDate = pCite:getValue 'DT-DATE'
-- Create / Update Marriage Event
local ptrMARR = fhGetItemPtr(data.principal.FAMILY.value, '~.MARR')
local sAction = 'Added'
if ptrMARR:IsNotNull() then
ptrMARR, sAction = fh.createUpdateFact(
data.principal.FAMILY.value,
'MARR',
'Marriage',
sPlace,
eventDate,
sAddress
)
else
ptrMARR = fh.createFact(
data.principal.FAMILY.value,
'MARR',
sPlace,
eventDate,
sAddress
)
end
if ptrMARR and ptrMARR:IsNotNull() then
local sPrincipal = 'HUSB'
local sSpouse = 'WIFE'
if data.principal.SEX.value == 'Female' then
local sPrincipal = 'WIFE'
local sSpouse = 'HUSB'
end
-- Add Ages
if data.principal.AGE then
local age = data.principal.AGE.value
if age:sub(1, 1) == 'f' or age:sub(1, 1) == 'F' then
age = '> 21'
end
local l = fhCreateItem(sPrincipal, ptrMARR)
local a = fhCreateItem('AGE', l, true)
local res = fhSetValueAsText(a, age)
end
if data.spouse.AGE then
local age = data.spouse.AGE.value
if age:sub(1, 1) == 'f' or age:sub(1, 1) == 'F' then
age = '> 21'
end
local l = fhCreateItem(sSpouse, ptrMARR)
local a = fhCreateItem('AGE', l, true)
res = fhSetValueAsText(a, age)
end
addCitation(ptrMARR, sAction)
end
for k, f in pairs(data) do
if f.RECORD and f.RECORD.value:IsNotNull() then
if f.OCCU and f.OCCU.value:len() > 0 then
local ptrFact
if k == 'principal' or k == 'spouse' then
-- 3/8/20 Remove place and address from Occupation
ptrFact = fh.createFact(
f.RECORD.value,
'OCCU',
nil,
eventDate,
nill,
f.OCCU.value,
f.AGE.value
)
else
if f.DECEASED and f.DECEASED.value then
ptrFact = fh.createFact(
f.RECORD.value,
'OCCU',
nil,
beforeDate(eventDate),
nil,
f.OCCU.value
)
else
ptrFact = fh.createFact(
f.RECORD.value,
'OCCU',
nil,
eventDate,
nil,
f.OCCU.value
)
end
end
if ptrFact then
addCitation(ptrFact, 'Added')
end
end
if f.DECEASED and f.DECEASED.value then
local ptrFact = fhGetItemPtr(f.RECORD.value, '~.DEAT')
local sAction
if ptrFact:IsNull() then
ptrFact = fh.createFact(
f.RECORD.value,
'DEAT',
nil,
beforeDate(eventDate)
)
if ptrFact then
addCitation(ptrFact, 'Added')
end
else
ptrFact, sAction = fh.createUpdateFact(
f.RECORD.value,
'DEAT',
'Death',
nil,
beforeDate(eventDate)
)
if ptrFact then
addCitation(ptrFact, sAction)
end
end
end
local dtBirth
if f.AGE then
local age = string.lower(f.AGE.value)
if age:sub(1, 1) == 'f' then
age = '21'
dtBirth = fh.calcBirth(eventDate, age)
dtBirth:SetRange('before', dtBirth:GetDatePt1())
else
dtBirth = fh.calcBirth(eventDate, f.AGE.value)
end
local ptrFact = fhGetItemPtr(f.RECORD.value, '~.BIRT')
ptrFact, sAction = fh.createUpdateFact(
f.RECORD.value,
'BIRT',
'Birth',
nil,
dtBirth
)
if ptrFact then
addCitation(ptrFact, sAction)
end
end
if f.PLAC and f.PLAC.value:len() > 0 then
local ptrFact, sAction = fh.createFact(
f.RECORD.value,
'RESI',
f.PLAC.value,
eventDate,
f.ADDR.value,
nil,
f.AGE.value
)
if ptrFact then
addCitation(ptrFact, 'Added')
end
end
if ptrMARR and f.WITNESS then
if f.ACTION.value == 'name' and fh.isSet(f.NAME.value) then
fh.addWitness(ptrMARR, f.NAME.value, 'Witness')
elseif fh.isSet(f.RECORD.value) then
fh.addWitness(ptrMARR, f.RECORD.value, 'Witness')
end
end
end
if f.ROLE and f.ROLE.value and f.CELEBRANT.value ~= '' then
-- Create Role for Celebrant in Marriage
fh.addWitness(ptrMARR, f.CELEBRANT.value, f.ROLE.value)
end
end
-- Output Text From Source
local fields = {}
for k, s in pairs(form) do
for i, f in ipairs(s.fields) do
local inx = string.upper(k .. '.' .. tostring(f.tag))
fields[inx] = fh.getParamValueForDisplay(f)
if f.tag == 'NAME' and data[k].RECORD then
local ptr = data[k].RECORD.value
if ptr:IsNotNull() then
-- Add record link
fields[inx] = fh.richTextRecordLink(ptr, fields[inx])
end
end
end
end
if not (pCite:checkRequired 'AD-ADDRESS') then
fields['AD-ADDRESS'] = ''
end
if not (pCite:checkRequired 'TX-CHURCH') then
fields['TX-CHURCH'] = ''
end
sText = fh.formatTextFromSource(templateName, templateDefault, pCite, fields)
ptrTextFromSource = fh.createTextFromSource(pCite, sText, 'source')
-- Output Final Result Set and Close.
fh.outputUpdatedFields(tUpdatedFields, pCite)
end
-- --------------------------------------------------------------- beforeDate
--- Add "before" to a date
-- @param dt fhDate
-- @return fhDate
function beforeDate(dt)
local newDate = fhNewDate()
if dt:IsNull() then
return
end
dp = dt:GetDatePt1()
if dp:IsNull() then
return
end
newDate:SetRange('before', dp)
return newDate
end
-- --------------------------------------------------------------- addCitation
--- add the current citation to an item and add it the output list
-- @param ptr fhItemPointer
-- @param action string value to output to the result set
function addCitation(ptr, action)
local action = action or ''
table.insert(tUpdatedFields, { ptr:Clone(), action })
pCite:appendCitation(ptr)
end
-- --------------------------------------------------------------- processParent
--- Check and add Parents as needed to a child
-- @param ptrParent Parent Record Pointer
-- @param ptrChild Child Record Pointer
function processParent(ptrParent, ptrChild)
local parentSex = fhGetItemText(ptrParent, 'SEX')
local ptrFamC = fhNewItemPtr()
local ptrHusb = fhNewItemPtr()
local ptrWife = fhNewItemPtr()
local bNewFam = true
ptrFamC:MoveTo(ptrChild, '~.FAMC')
while ptrFamC:IsNotNull() do
ptrHusb:MoveTo(ptrFamC, '~>HUSB>')
ptrWife:MoveTo(ptrFamC, '~>WIFE>')
if ptrHusb:IsSame(ptrParent) or ptrWife:IsSame(ptrParent) then
bNewFam = false
end
ptrFamC:MoveNext 'SAME_TAG'
end
if bNewFam then
ptrFam = fh.createFamilyAsChild(ptrChild)
fh.addFamilyAsSpouse(ptrParent, ptrFam)
addCitation(ptrFam, 'Created')
end
end
-- --------------------------------------------------------------- selectOrCreate
--- ChildUpdate handler
-- @param value string - value of list box
-- @return boolean - true if value select
function selectOrCreate(value)
if value == 'select' then
return false, 1
else
return true, 0
end
end
-- --------------------------------------------------------------- updateFamList
--- Updates Prompts for the Family list on the principle.
-- @param ptr Principles pointer
-- @return table fhItemPointer, family list pointers
-- @return table string,family list descriptions
function updateFamList(ptr, fields)
local ptrs = {}
local prompts = {}
local famList = fh.familyList(ptr, 'FamilyAsSpouse')
for i, tFam in ipairs(famList) do
table.insert(ptrs, tFam.ptr)
table.insert(prompts, tFam.label)
end
-- Set Sex Field
if ptr:IsNotNull() and fields and fields[5] and fields[5].iupcontrol then
local sSex = fhGetItemText(ptr, '~.SEX')
if sSex == 'Male' then
fields[5].iupcontrol.value = 1
else
fields[5].iupcontrol.value = 2
end
end
return ptrs, prompts
end
-- --------------------------------------------------------------- field
--- get the field index from the tag
-- @param fields table of fields
-- @param tag string value of field tag
-- @return integer number of field in fields list
function field(fields, tag)
local i
for i, v in ipairs(fields) do
if tag == v.tag then
return i
end
end
end
-- --------------------------------------------------------------- address
--- getParam helper returns list of addresses for place
-- @param place string, place name
-- @return table of matching addresses
function address(place)
local addr = fh.createAddressList(place)
return addr
end
function loadMasterForms()
ptrFamily = fhNewItemPtr()
masterForms = {}
masterForms[1] = {
templateName = 'Marriage Certificate (UK).ftf',
templateDefault = [[Marriage of {NM-PRINCIPAL} and {NM-PRINCIPAL_2}
Certified Copy of an entry of Marriage
Registration District {ADDITIONAL.DISTRICT}
Place | Venue | Celebrant | Type | Reference
{PL-LOCATION} | {TX-CHURCH} {AD-ADDRESS} | {ADDITIONAL.CELEBRANT} {ADDITIONAL.ROLE} | {ADDITIONAL.TYPE} |{TX-REFERENCE}
When Married | Name and Surname | Age | Condition | Rank or Profession | Residence at time of Marriage | Fathers Name | Fathers Occupation
{DT-DATE} | {PRINCIPAL.NAME} | {PRINCIPAL.AGE} | {PRINCIPAL.CONDITION} | {PRINCIPAL.OCCU} | {PRINCIPAL.ADDR}
{PRINCIPAL.PLAC} | {FATHERPRINCIPAL.NAME} | {FATHERPRINCIPAL.OCCU}
{FATHERPRINCIPAL.DECEASED}
| {SPOUSE.NAME} | {SPOUSE.AGE} | {SPOUSE.CONDITION} | {SPOUSE.OCCU} | {SPOUSE.ADDR}
{SPOUSE.PLAC} | {FATHERSPOUSE.NAME} | {FATHERSPOUSE.OCCU}
{FATHERSPOUSE.DECEASED}
Witnessed by {WITNESS1.NAME} , {WITNESS2.NAME}
Reference {TX-REFERENCE}
]],
sections = {
principal = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = pCite:getValue 'NM-PRINCIPAL',
minlength = 1,
protect = true,
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add principal as',
type = 'LIST',
value = 'create',
values = { 'create', 'select' },
prompts = { 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = function(...)
return selectOrCreate(...)
end,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
dr = 'PTR',
value = fhNewItemPtr(),
protect = true,
child = 'FAMILY',
childUpdate = function(...)
return updateFamList(...)
end,
},
{
tag = 'FAMILY',
label = 'Family',
type = 'LIST',
value = ptrFamily,
values = { ptrFamily },
prompts = { 'New Family as Spouse' },
},
{
tag = 'SEX',
type = 'LIST',
label = 'Sex',
dr = 'SEX',
value = 'Male',
values = { 'Male', 'Female', 'Unknown' },
},
{
tag = 'AGE',
type = 'STRING',
label = 'Age (or full)',
dr = 'AGE',
value = '',
mask = '(/d+[dwmyf]|full|Full)',
minlength = 1,
},
{
tag = 'CONDITION',
type = 'STRING',
label = 'Condition',
value = '',
minlength = 1,
},
{ tag = 'OCCU', dr = 'OCCU', type = 'STRING', label = 'Occupation', value = '' },
{
tag = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = address,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
{ tag = 'BIRT', dr = 'BIRT' },
},
title = 'Principal',
label = 'principal',
seq = 1,
editActive = true,
gridDisplay = true,
},
fatherPrincipal = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add father as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = { 'Name Only', 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{ tag = 'OCCU', dr = 'OCCU', type = 'STRING', label = 'Occupation', value = '' },
{ tag = 'DECEASED', type = 'BOOLEAN', label = 'Deceased', value = false },
{ tag = 'SEX', value = 'Male' },
},
title = 'Father of principal',
seq = 2,
gridDisplay = false,
},
spouse = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = pCite:getValue 'NM-PRINCIPAL_2',
minlength = 1,
protect = true,
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add spouse as',
type = 'LIST',
value = 'create',
values = { 'create', 'select' },
prompts = { 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
protect = false,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{
tag = 'SEX',
type = 'LIST',
label = 'Sex',
dr = 'SEX',
value = 'Female',
values = { 'Male', 'Female', 'Unknown' },
},
{
tag = 'AGE',
type = 'STRING',
label = 'Age (or full)',
dr = 'AGE',
value = '',
mask = '(/d+[dwmyf]|full|Full)',
minlength = 1,
},
{
tag = 'CONDITION',
type = 'STRING',
label = 'Condition',
value = '',
minlength = 1,
},
{ tag = 'OCCU', dr = 'OCCU', type = 'STRING', label = 'Occupation', value = '' },
{
tag = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = address,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
{ tag = 'BIRT', dr = 'BIRT' },
},
title = 'Spouse',
seq = 3,
gridDisplay = false,
},
fatherSpouse = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add Father as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = { 'Name Only', 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{ tag = 'OCCU', dr = 'OCCU', type = 'STRING', label = 'Occupation', value = '' },
{ tag = 'DECEASED', type = 'BOOLEAN', label = 'Deceased', value = false },
{ tag = 'SEX', value = 'Male' },
},
title = 'Father of Spouse',
seq = 4,
gridDisplay = false,
},
witness1 = {
fields = {
{
tag = 'NAME',
label = 'Witness Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
},
{
tag = 'ACTION',
label = 'Add witness as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = { 'Name only', 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{ tag = 'WITNESS', dr = 'SHA' },
},
title = 'Witness 1',
seq = 5,
gridDisplay = false,
},
witness2 = {
fields = {
{
tag = 'NAME',
label = 'Witness Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
},
{
tag = 'ACTION',
label = 'Add witness as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = { 'Name only', 'Create New Record', 'Use Existing Record' },
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{ tag = 'WITNESS', dr = 'SHA' },
},
title = 'Witness 2',
seq = 6,
gridDisplay = false,
},
additional = {
fields = {
{
tag = 'CELEBRANT',
label = 'Celebrant',
type = 'STRING',
dr = 'NAME',
value = '',
},
{
tag = 'ROLE',
label = 'Role',
type = 'LIST',
value = 'None',
values = { 'None', 'Minister', 'Registrar' },
},
{
tag = 'TYPE',
label = 'Marriage Type',
type = 'LIST',
value = '',
values = {
'',
'By Banns',
'After Banns',
'By Licence',
'By Certificate',
},
},
{
tag = 'DISTRICT',
label = 'Registration District',
type = 'STRING',
dr = 'NAME',
value = '',
},
},
title = 'Additional Information',
seq = 7,
gridDisplay = false,
},
},
}
-- Set up Parish Varient
masterForms[2] = tablex.deepcopy(masterForms[1])
masterForms[2].templateName = 'Church Marriage (UK).ftf'
masterForms[2].templateDefault =
[[Marriage of {NM-PRINCIPAL} and {NM-PRINCIPAL_2}
Place | Church | Celebrant | Type | Reference
{PL-LOCATION} | {TX-CHURCH} {AD-ADDRESS} | {ADDITIONAL.CELEBRANT} {ADDITIONAL.ROLE} | {ADDITIONAL.TYPE} |{TX-REFERENCE}
When Married | Name and Surname | Age | Condition | Rank or Profession | Residence at time of Marriage | Fathers Name | Fathers Occupation
{DT-DATE} | {PRINCIPAL.NAME} | {PRINCIPAL.AGE} | {PRINCIPAL.CONDITION} | {PRINCIPAL.OCCU} | {PRINCIPAL.ADDR}
{PRINCIPAL.PLAC} | {FATHERPRINCIPAL.NAME} | {FATHERPRINCIPAL.OCCU}
{FATHERPRINCIPAL.DECEASED}
| {SPOUSE.NAME} | {SPOUSE.AGE} | {SPOUSE.CONDITION} | {SPOUSE.OCCU} | {SPOUSE.ADDR}
{SPOUSE.PLAC} | {FATHERSPOUSE.NAME} | {FATHERSPOUSE.OCCU}
{FATHERSPOUSE.DECEASED}
Witnessed by {WITNESS1.NAME} , {WITNESS2.NAME}
Reference {TX-REFERENCE}
]]
-- Remove Civil Information fields.
-- TODO
masterForms[2].sections.additional.fields[4] = nil
return masterForms
end
-------------------------------------------------------------------------------------------------------- Start Plugin
main()
Source:Record-Marriage-Data-UK-7.fh_lua