Record Birth Data UK.fh_lua--[[
@Title: Record Birth Data (UK and Ireland)
@Type: Source-driven Data Entry
@Subtype: "Civil Registration Certificate"
@Author: Calico Pie
@Contributor: Helen Wright
@Version: 1.7
@Keywords:
@LastUpdated: November 2021
@GH #24 #37 #54 #66 #76 #88 #112 #119
@Description:
This plugin allows the entry of details from a birth certificate and creates records for individuals named if needed, as well as recording residence, occupation birth and death facts.
Supports UK and Ireland Birth certificates
England and Wales
Scotland (not 1855)
Isle of Man (you should create an Isle of Man region)
Channel Islands (you should create a Channel Islands region)
Ireland
Northern Ireland (you should create a Northern Ireland region)
]]
fhInitialise(7, 0, 0)
fh = require 'fhUtils'
fh.setIupDefaults()
stringx.import()
-- Local Globals
local form, templateName, templateDefault
local sRegionName
local sPluginName = fhGetContextInfo 'CI_PLUGIN_NAME'
local s = {} -- Autofill table
local pCite, iRegion, iYear -- Citation Object
local tUpdatedFields = {} -- Added and updated fields
local cells = {} -- Main Dialog sections
--- Builds dialog and drives process.
function main()
-- ------------------------------------------------------------Load citation and associated fields
pCite = fh.loadPreparedCitation()
if not pCite.result then
fh.getParam(sPluginName, pCite.err)
return
end
-- Ensure all needed fields have been completed
if
not (
pCite:checkRequired(
'EN-REGION',
'EN-TYPE',
'NM-PRINCIPAL',
'DT-DATE',
'PL-LOCATION'
)
)
then
fh.getParam(
sPluginName,
'Not all required fields are set,\nplease ensure you have entered type, date, location and principal. '
)
return
end
if pCite:getValue 'EN-TYPE' ~= 'Birth' then
fh.getParam(sPluginName, 'Only Birth is supported by this plugin. ')
return
end
-- Get form and load values from Citation
sRegionName = pCite:getValue 'EN-REGION'
local masterForms = loadMasterForms()
if not masterForms[sRegionName] then
fh.getParam(sPluginName, 'Sorry ' .. sRegionName .. ' not supported.')
return
end
form = tablex.deepcopy(masterForms[sRegionName]['sections'])
templateName = masterForms[sRegionName]['templateName']
templateDefault = masterForms[sRegionName]['templateDefault']
form.principal.fields[1].value = pCite:getValue 'NM-PRINCIPAL'
dtEventDateString = pCite:getDisplayValue 'DT-DATE'
dtEventDate = pCite:getValue 'DT-DATE'
-- ------------------------------------------------------------ Get currently selected person
local ptrPrincipal = fh.getCurrentIndividual()
if ptrPrincipal:IsNotNull() then
form.principal.fields[field(form.principal.fields, 'RECORD')].value =
ptrPrincipal:Clone()
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',
}
for l, f in ipairs(v.fields) do
if f.label then
local label = string.rep(' ', f.label:len()) .. ' '
local value = ' '
if f.gridDisplay or v.gridDisplay then
label = f.label .. ':'
value = fh.getParamValueForDisplay(f, true)
if value == f.label then
value = utils.choose(f.value == true, 'Yes', 'No')
end
end
f.gridLabel = iup.label {
title = label,
size = '80',
expand = 'HORIZONTAL',
}
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.active 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
local placeList = fh.createPlaceList()
s['PLAC'] = placeList
s['OCCU'] = {} -- TODO
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 then
local sVenue = pCite:getValue 'TX-CHURCH'
if not sVenue then
sVenue = pCite:getValue 'AD-ADDRESS'
end
processBirth(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 = 'Birth 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-birth-data-uk',
txtMessage,
},
},
}
iup.SetAttribute(dlg, 'NATIVEPARENT', fhGetContextInfo 'CI_PARENT_HWND') -- Set the parent window handle iup.SetHandle("main", dlg)
iup.SetGlobal('PARENTDIALOG', 'main')
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
if sType == 'principal' then
local oldRecord =
form[sType]['fields'][field(fields, 'RECORD')].value:Clone()
local oldFamily = form[sType]['fields'][field(fields, 'FAMILY')]
if oldFamily.value then
oldFamily = oldFamily.value:Clone()
else
oldFamily = fhNewItemPtr()
end
local r = fh.getParam(
'Enter ' .. sTitle,
nil,
fields,
{ 'OK', 'Cancel', fh.helpButton 'record-marriage-data-uk-principal' },
s
)
if r.ok then
form[sType].valid = 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' },
s
)
if r.ok then
form[sType].valid = true
form[sType].gridDisplay = true
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
if init then
-- first time load or new Record selected
local values, prompts = updateFamList(ptrPrincipal, 'FamilyAsChild')
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
f[field(f, 'SEX')].value = fhGetItemText(ptrPrincipal, '~.SEX')
-- f[field(f,'SEX')].protect = true
local ptrFam = f[field(f, 'FAMILY')].value
if ptrFam:IsNotNull() then
-- Set up Father of Principal if they exist
local ptrF = fhGetItemPtr(ptrFam, '~.HUSB>')
if ptrF:IsNotNull() then
local s = form['father'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrF:Clone()
s[field(s, 'RECORD')].protect = true
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'ACTION')].protect = true
end
-- Set up Mother of Principal if they exist
local ptrF = fhGetItemPtr(ptrFam, '~.WIFE>')
if ptrF:IsNotNull() then
local s = form['mother'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrF:Clone()
s[field(s, 'RECORD')].protect = true
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'ACTION')].protect = true
end
else
resetSection 'father'
resetSection 'mother'
end
else
resetSection 'father'
resetSection 'mother'
end
end
-- --------------------------------------------------------------- resetSection
--- Reset the section values from the master form
-- @param formSection string section index
function resetSection(formSection)
for k, v in ipairs(form[formSection]['fields']) do
for m, u in pairs(v) do
form[formSection]['fields'][k][m] = u
end
end
updateGrid()
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)
if value == f.label then
value = utils.choose(f.value == true, 'Yes', 'No')
end
end
if f.gridLabel then
f.gridLabel.title = label
end
if f.iupgrid then
f.iupgrid.title = value
end
end
end
end
function processBirth(sPlace, sAddress, sCelebrant)
local fields = {}
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')
local ptrName = fhGetItemPtr(ptr, '~.NAME')
addCitation(ptrName, 'Cited')
f.RECORD.value:MoveTo(ptr)
end
end
local ptrfamC = processParents(
data.father.RECORD.value,
data.mother.RECORD.value,
data.principal.RECORD.value
)
local eventDate = pCite:getValue 'DT-DATE'
local sPlace = pCite:getValue 'PL-LOCATION'
local sAddress = pCite:getValue 'AD-ADDRESS'
-- Create / Update Birth Event
local ptrBirth = fhGetItemPtr(data.principal.RECORD.value, '~.BIRT')
local sAction = ''
if ptrBirth:IsNotNull() then
ptrBirth, sAction = fh.createUpdateFact(
data.principal.RECORD.value,
'BIRT',
'Birth',
sPlace,
eventDate,
sAddress
)
if ptrBirth then
addCitation(ptrBirth, sAction)
end
else
ptrBirth = fh.createFact(
data.principal.RECORD.value,
'BIRT',
sPlace,
eventDate,
sAddress
)
if ptrBirth then
addCitation(ptrBirth, 'Added')
end
end
for k, f in pairs(data) do
if ptrBirth and k == 'informant' then
if f.RELATIONSHIP.value == 'Father' then
f.RECORD.value:MoveTo(data.father.RECORD.value)
f.ACTION.value = data.father.ACTION.value
end
if f.RELATIONSHIP.value == 'Mother' then
f.RECORD.value:MoveTo(data.mother.RECORD.value)
f.ACTION.value = data.mother.ACTION.value
end
if f.ACTION.value == 'name' and fh.isSet(f.NAME.value) then
fh.addWitness(ptrBirth, f.NAME.value, 'Informant')
elseif fh.isSet(f.RECORD.value) then
fh.addWitness(ptrBirth, f.RECORD.value, 'Informant')
end
end
if f.RECORD and fh.isSet(f.RECORD.value) then
if f.OCCU and f.OCCU.value:len() > 0 then
local ptrFact
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
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 = 'Added'
local deathdate = utils.choose(
data.reg.DATE.value:IsNull(),
beforeDate(eventDate),
beforeDate(data.reg.DATE.value)
)
if ptrFact:IsNotNull() then
ptrFact, sAction = fh.createUpdateFact(
f.RECORD.value,
'DEAT',
'Death',
nil,
deathdate,
nil
)
else
ptrFact = fh.createFact(f.RECORD.value, 'DEAT', nil, deathdate, nil)
end
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
)
if ptrFact then
addCitation(ptrFact, 'Added')
end
end
if
f.MARRIAGEDATE
and not (f.MARRIAGEDATE.value:IsNull())
and not (ptrfamC:IsNull())
then --create marriage event
processMarriage(
ptrfamC,
f.MARRIAGEPLACE.value,
f.MARRIAGEADDRESS.value,
f.MARRIAGEDATE.value
)
end
if
k == 'mother'
and f.RECORD.value:IsNotNull()
and fh.isSet(f.MAIDEN_NAME.value)
then
local surname = fh.getSurname(
fhGetItemText(f.RECORD.value, '~.NAME:STORED')
)
local maiden = fh.getSurname(f.MAIDEN_NAME.value)
if surname:upper() ~= maiden:upper() then
if
fh.yes(
'Update Mothers Surname from '
.. surname:upper()
.. ' to '
.. maiden:upper()
)
then
local mothersName = fhGetItemText(f.RECORD.value, '~.NAME:STORED')
mothersName = stringx.replace(
mothersName,
'/' .. surname .. '/',
'/' .. maiden .. '/'
)
local ptrName = fhGetItemPtr(f.RECORD.value, '~.NAME')
if ptrName:IsNotNull() then
fhSetValueAsText(ptrName, mothersName)
if f.ACTION and f.ACTION.value ~= 'create' then
addCitation(ptrName, 'Updated')
end
end
end
end
end
end
end
-- 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 fields['INFORMANT.RELATIONSHIP'] == 'Other' then
fields['INFORMANT.RELATIONSHIP'] = fields['INFORMANT.OTHER']
end
-- Add prefix if the maiden name field has a value
if fields['MOTHER.MAIDEN_NAME']:strip() ~= '' then
if sRegionName == 'Scotland' then
fields['MOTHER.MAIDEN_NAME'] = 'Maiden name\n'
.. fields['MOTHER.MAIDEN_NAME']
else
fields['MOTHER.MAIDEN_NAME'] = 'formerly\n'
.. fields['MOTHER.MAIDEN_NAME']
end
end
--Add prefix if residence of one or other parent is defined
if fields['MOTHER.ADDR']:strip() ~= '' then
fields['MOTHER.ADDR'] = 'at ' .. fields['MOTHER.ADDR']
elseif fields['MOTHER.PLAC']:strip() ~= '' then
fields['MOTHER.PLAC'] = 'at ' .. fields['MOTHER.PLAC']
end
if fields['FATHER.ADDR']:strip() ~= '' then
fields['FATHER.ADDR'] = 'at ' .. fields['FATHER.ADDR']
elseif fields['FATHER.PLAC']:strip() ~= '' then
fields['FATHER.PLAC'] = 'at ' .. fields['FATHER.PLAC']
end
if fields['FATHER.DECEASED']:strip() ~= '' then
fields['FATHER.OCCU'] = fields['FATHER.OCCU'] .. ' (deceased)'
end
if fields['MOTHER.DECEASED']:strip() ~= '' then
fields['MOTHER.OCCU'] = fields['MOTHER.OCCU'] .. ' (deceased)'
end
if sRegionName == 'Scotland' then
fields['PRINCIPAL.YEAR'] = dtEventDate:GetDisplayText 'YEAR'
fields['BIRTH.DAY'] = dtEventDate:GetDisplayText 'DAY'
fields['BIRTH.MONTH'] = dtEventDate:GetDisplayText 'MONTH_NAME'
fields['BIRTH.YEAR'] = dtEventDate:GetDisplayText 'YEAR'
if not form.reg.fields[7].value:IsNull() then
fields['REG.YEAR'] = form.reg.fields[7].value:GetDisplayText 'YEAR'
fields['REG.DAY'] = form.reg.fields[7].value:GetDisplayText 'DAY'
fields['REG.MONTH'] = form.reg.fields[7].value:GetDisplayText 'MONTH_NAME'
end
if fields['REG.DISTRICT']:strip() ~= '' then -- add prefix to Registration district
fields['REG.DISTRICT'] = 'at ' .. fields['REG.DISTRICT']
end
if not form.mother.fields[6].value:IsNull() then
fields['MOTHER.MARRIAGEYEAR'] =
form.mother.fields[6].value:GetDisplayText 'YEAR'
fields['MOTHER.MARRIAGEDAY'] =
form.mother.fields[6].value:GetDisplayText 'DAY'
fields['MOTHER.MARRIAGEMONTH'] =
form.mother.fields[6].value:GetDisplayText 'MONTH_NAME'
end
end
sText = fh.formatTextFromSource(templateName, templateDefault, pCite, fields)
fh.createTextFromSource(pCite, sText, 'source')
fh.outputUpdatedFields(tUpdatedFields, pCite)
end
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
function addCitation(ptr, action)
local action = action or ''
table.insert(tUpdatedFields, { ptr:Clone(), action })
pCite:appendCitation(ptr)
end
function processParents(ptrFather, ptrMother, ptrChild)
local ptrFamC = fhNewItemPtr()
local ptrFam = fhNewItemPtr()
local ptrHusb = fhNewItemPtr()
local ptrWife = fhNewItemPtr()
local bFamc = false
ptrFamC:MoveTo(ptrChild, '~.FAMC')
while ptrFamC:IsNotNull() do
ptrHusb:MoveTo(ptrFamC, '~>HUSB>')
ptrWife:MoveTo(ptrFamC, '~>WIFE>')
if
ptrHusb:IsSame(ptrFather)
and (ptrWife:IsSame(ptrMother) or ptrWife:IsNull())
then
ptrFam:MoveTo(ptrFamC, '~>')
bFamc = true
elseif
ptrWife:IsSame(ptrMother)
and (ptrHusb:IsSame(ptrFather) or ptrHusb:IsNull())
then
ptrFam:MoveTo(ptrFamC, '~>')
bFamc = true
end
ptrFamC:MoveNext 'SAME_TAG'
end
-- Check if selected people already married
if not bFamc then
local ptrChk = fhGetItemPtr(ptrFather, '~.FAMS')
local ptrWifeChk = fhNewItemPtr()
while ptrChk:IsNotNull() do
ptrWifeChk:MoveTo(ptrChk, '~>WIFE>')
if ptrWifeChk:IsSame(ptrMother) then
ptrFam:MoveTo(ptrChk, '~>')
end
ptrChk:MoveNext 'SAME_TAG'
end
if ptrFam:IsNotNull() then
fh.addFamilyAsChild(ptrChild, ptrFam)
end
end
if ptrFather:IsNotNull() or ptrMother:IsNotNull() then
if ptrFam:IsNull() then
ptrFam = fh.createFamilyAsChild(ptrChild)
addCitation(ptrFam, 'Created')
end
if fhGetItemPtr(ptrFam, '~.HUSB>'):IsNull() and ptrFather:IsNotNull() then
fh.addFamilyAsSpouse(ptrFather, ptrFam)
end
if fhGetItemPtr(ptrFam, '~.WIFE>'):IsNull() and ptrMother:IsNotNull() then
fh.addFamilyAsSpouse(ptrMother, ptrFam)
end
end
return ptrFam
end
function processMarriage(ptrFam, sPlace, sAddress, ptrDate)
if ptrFam:IsNotNull() then
local ptrMARR = fhGetItemPtr(ptrFam, '~.MARR')
local sAction
if ptrMARR:IsNotNull() then
ptrMARR, sAction = fh.createUpdateFact(
ptrFam,
'MARR',
'Marriage',
sPlace,
ptrDate,
sAddress
)
if ptrMarr then
addCitation(ptrMARR, sAction)
end
else
ptrMARR = fh.createFact(ptrFam, 'MARR', sPlace, ptrDate, sAddress)
if ptrMarr then
addCitation(ptrMARR, 'Added')
end
end
end
end
function ptrDescription(ptr)
local strDesc = ''
local strTag = fhGetTag(ptr)
if not (fhHasParentItem(ptr)) then
strDesc = 'Record (' .. fhGetTag(ptr) .. ')'
else
local strTitle = string.match(fhGetDisplayText(ptr), '([%a%w%s]*):')
if not strTitle then
strTitle = string.match(fhGetDisplayText(ptr), '(%a*)')
end
strDesc = strTitle .. ' (' .. strTag .. ')'
end
return strDesc
end
function selectOrCreate(value)
if value == 'select' then
return false, 1
else
return true, 0
end
end
function selectOrCreatePrincipal()
if value == 'select' then
return false, 1
else
-- data.principal.SEX.protect = false
return true, 0
end
end
function updateFamList(ptr)
local ptrs = { fhNewItemPtr() }
local prompts = { 'New Family As Child' }
if fh.isSet(ptr) then
local famList = fh.familyList(ptr, 'FamilyAsChild')
for i, tFam in ipairs(famList) do
table.insert(ptrs, tFam.ptr)
table.insert(prompts, tFam.label)
end
end
return ptrs, prompts
end
function field(fields, tag)
local i
for i, v in ipairs(fields) do
if tag == v.tag then
return i
end
end
end
function updateAddressList(...)
args = { ... }
print ',,,'
end
function loadMasterForms()
ptrFamily = fhNewItemPtr()
local masterForms = {}
masterForms['England and Wales'] = {
templateName = 'Birth Certificate (England and Wales).ftf',
templateDefault = [[Birth certificate {NM-PRINCIPAL} {DT-DATE}
Certified Copy of an entry of Birth given at {REG.LOCATION} Registration District {REG.DISTRICT} in sub-district of {REG.SUB} in the county of {REG.PLAC}
When and Where born | Name if any | Sex | Name and surname of Father | Name, Surname and maiden name of Mother | Occupation of Father | Signature, description and residence of informant | When Registered | Signature of Registrar | Name entered after registration
{DT-DATE}
{AD-ADDRESS}
{PL-LOCATION} | {PRINCIPAL.NAME} | {PRINCIPAL.SEX} | {FATHER.NAME} | {MOTHER.NAME}
{MOTHER.OCCU}
{MOTHER.ADDR}
{MOTHER.PLAC}
{MOTHER.MAIDEN_NAME} | {FATHER.OCCU}
{FATHER.ADDR}
{FATHER.PLAC} | {INFORMANT.NAME}
{INFORMANT.RELATIONSHIP}
{INFORMANT.ADDR}
{INFORMANT.PLAC} | {REG.DATE} | {REG.NAME} | {REG.AFTER}
]],
sections = {
reg = {
fields = {
{
tag = 'LOCATION',
type = 'STRING',
label = 'Registry',
value = 'General Register Office',
},
{
tag = 'DISTRICT',
type = 'STRING',
label = 'District',
value = '',
},
{
tag = 'SUB',
type = 'STRING',
label = 'Sub-District',
value = '',
},
{ tag = 'PLAC', type = 'STRING', label = 'County of', value = '' },
{
tag = 'NAME',
type = 'STRING',
label = 'Registrars Name',
value = '',
},
{
tag = 'AFTER',
type = 'STRING',
label = 'Name Entered After Registration',
value = '',
},
{
tag = 'DATE',
type = 'DATE',
label = 'Registration Date',
value = fhNewDate(),
},
},
title = 'Registration Information',
label = 'principal',
seq = 1,
active = true,
},
principal = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = pCite:getValue 'NM-PRINCIPAL',
minlength = 1,
protect = 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 Child' },
},
{
tag = 'SEX',
type = 'LIST',
label = 'Sex',
dr = 'SEX',
value = 'Male',
values = { 'Male', 'Female', 'Unknown' },
},
{ tag = 'BIRT', dr = 'BIRT' },
},
title = 'Principal',
label = 'principal',
seq = 2,
active = true,
gridDisplay = true,
},
father = {
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 = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = function(place)
return fh.createAddressList(place)
end,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
{ tag = 'SEX', value = 'Male' },
},
title = 'Father of principal',
seq = 3,
},
mother = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
gridDisplay = true,
},
{
tag = 'MAIDEN_NAME',
label = 'Maiden Surname',
type = 'STRING',
value = '',
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add mother as',
type = 'LIST',
value = 'create',
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 = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = function(place)
return fh.createAddressList(place)
end,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
{ tag = 'SEX', value = 'Female' },
},
title = 'Mother of principal',
seq = 4,
},
informant = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
},
{
tag = 'RELATIONSHIP',
label = 'Relationship',
type = 'LIST',
value = '',
values = { 'Father', 'Mother', 'Other' },
minlength = 1,
},
{
tag = 'OTHER',
label = 'Relationship (Other)',
type = 'STRING',
value = '',
},
{
tag = 'ACTION',
label = 'Add informant as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = {
'Name Only/Parent',
'Create New Record',
'Use Existing Record',
},
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{
tag = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = function(place)
return fh.createAddressList(place)
end,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
},
title = 'Informant',
seq = 5,
},
},
}
masterForms['Scotland'] = tablex.deepcopy(masterForms['England and Wales'])
masterForms['Scotland']['templateName'] = 'Birth Certificate (Scotland).ftf'
masterForms['Scotland']['templateDefault'] =
[[Birth {NM-PRINCIPAL} {DT-DATE}
Surname and name (if given)
Name if altered after registration| When and Where born with hour of birth| Sex| Name, surname, and rank or profession of father | Name, and maiden surname
of mother
Date and place of marriage| Signature, qualification and residence of informant,
if out of the house in which the birth occurred| When and where registered and signature of registrar
{PRINCIPAL.NAME}
{REG.AFTER}| {BIRTH.YEAR}
{BIRTH.MONTH}
{BIRTH.DAY}
{PRINCIPAL.TIME}
{AD-ADDRESS}
{PL-LOCATION}| {PRINCIPAL.SEX}| {FATHER.NAME}
{FATHER.OCCU}| {MOTHER.NAME}
{MOTHER.MAIDEN_NAME}
{MOTHER.MARRIAGEYEAR}
{MOTHER.MARRIAGEMONTH}
{MOTHER.MARRIAGEDAY}
{MOTHER.MARRIAGEPLACE}| {INFORMANT.NAME}
{INFORMANT.RELATIONSHIP}
{INFORMANT.ADDR}
{INFORMANT.PLAC}| {REG.YEAR}
{REG.MONTH}
{REG.DAY}
{REG.DISTRICT}
{REG.NAME}
The above particulars are extracted from a Register of births for the Parish of {REG.DISTRICT}
in the County of {REG.PLAC}
Given under the Seal of the {REG.LOCATION}
]]
masterForms['Scotland']['sections']['reg']['fields'][1] = {
tag = 'LOCATION',
type = 'STRING',
label = 'Registry',
value = 'Registrar General for Scotland',
}
table.insert(
masterForms['Scotland']['sections']['principal']['fields'],
6,
{ tag = 'TIME', type = 'STRING', label = 'Birth time', value = '' }
)
table.insert(
masterForms['Scotland']['sections']['mother']['fields'],
6,
{
tag = 'MARRIAGEDATE',
type = 'DATE',
label = 'Marriage Date',
value = fhNewDate(),
}
)
table.insert(
masterForms['Scotland']['sections']['mother']['fields'],
7,
{
tag = 'MARRIAGEPLACE',
type = 'STRING',
label = 'Marriage Place',
value = '',
}
)
table.insert(
masterForms['Scotland']['sections']['mother']['fields'],
8,
{
tag = 'MARRIAGEADDRESS',
type = 'STRING',
label = 'Marriage Address',
value = '',
}
)
masterForms['Ireland'] = tablex.deepcopy(masterForms['England and Wales'])
masterForms['Ireland']['templateName'] = 'Birth Certificate (Ireland).ftf'
--fields and template assumed same as E&W
masterForms['Northern Ireland'] = tablex.deepcopy(
masterForms['England and Wales']
)
masterForms['Northern Ireland']['templateName'] =
'Birth Certificate (Northern Ireland).ftf'
masterForms['Northern Ireland']['sections']['reg']['fields'][1] = {
tag = 'LOCATION',
type = 'STRING',
label = 'Registry',
value = 'General Register Office (Northern Ireland)',
}
--other fields and template assumed same as E&W
masterForms['Isle of Man'] = tablex.deepcopy(masterForms['England and Wales'])
masterForms['Isle of Man']['templateName'] =
'Birth Certificate (Isle of Man).ftf'
masterForms['Isle of Man']['sections']['reg']['fields'][1] = {
tag = 'LOCATION',
type = 'STRING',
label = 'Registry',
value = 'Civil Registry',
}
--other fields and template assumed same as E&W
masterForms['Channel Islands'] = tablex.deepcopy(
masterForms['England and Wales']
)
masterForms['Channel Islands']['templateName'] =
'Birth Certificate (Channel Islands).ftf'
masterForms['Channel Islands']['sections']['reg']['fields'][1] = {
tag = 'LOCATION',
type = 'LIST',
label = 'Registry',
value = '',
values = {
'The Superintendent Registrar',
'HM Greffier',
'The Greffier',
'The Greffe',
},
}
return masterForms
end
-------------------------------------------------------------------------------------------------------- Start Plugin
main()
--[[
@Title: Record Birth Data (UK and Ireland)
@Type: Source-driven Data Entry
@Subtype: "Civil Registration Certificate"
@Author: Calico Pie
@Contributor: Helen Wright
@Version: 1.7
@Keywords:
@LastUpdated: November 2021
@GH #24 #37 #54 #66 #76 #88 #112 #119
@Description:
This plugin allows the entry of details from a birth certificate and creates records for individuals named if needed, as well as recording residence, occupation birth and death facts.
Supports UK and Ireland Birth certificates
England and Wales
Scotland (not 1855)
Isle of Man (you should create an Isle of Man region)
Channel Islands (you should create a Channel Islands region)
Ireland
Northern Ireland (you should create a Northern Ireland region)
]]
fhInitialise(7, 0, 0)
fh = require 'fhUtils'
fh.setIupDefaults()
stringx.import()
-- Local Globals
local form, templateName, templateDefault
local sRegionName
local sPluginName = fhGetContextInfo 'CI_PLUGIN_NAME'
local s = {} -- Autofill table
local pCite, iRegion, iYear -- Citation Object
local tUpdatedFields = {} -- Added and updated fields
local cells = {} -- Main Dialog sections
--- Builds dialog and drives process.
function main()
-- ------------------------------------------------------------Load citation and associated fields
pCite = fh.loadPreparedCitation()
if not pCite.result then
fh.getParam(sPluginName, pCite.err)
return
end
-- Ensure all needed fields have been completed
if
not (
pCite:checkRequired(
'EN-REGION',
'EN-TYPE',
'NM-PRINCIPAL',
'DT-DATE',
'PL-LOCATION'
)
)
then
fh.getParam(
sPluginName,
'Not all required fields are set,\nplease ensure you have entered type, date, location and principal. '
)
return
end
if pCite:getValue 'EN-TYPE' ~= 'Birth' then
fh.getParam(sPluginName, 'Only Birth is supported by this plugin. ')
return
end
-- Get form and load values from Citation
sRegionName = pCite:getValue 'EN-REGION'
local masterForms = loadMasterForms()
if not masterForms[sRegionName] then
fh.getParam(sPluginName, 'Sorry ' .. sRegionName .. ' not supported.')
return
end
form = tablex.deepcopy(masterForms[sRegionName]['sections'])
templateName = masterForms[sRegionName]['templateName']
templateDefault = masterForms[sRegionName]['templateDefault']
form.principal.fields[1].value = pCite:getValue 'NM-PRINCIPAL'
dtEventDateString = pCite:getDisplayValue 'DT-DATE'
dtEventDate = pCite:getValue 'DT-DATE'
-- ------------------------------------------------------------ Get currently selected person
local ptrPrincipal = fh.getCurrentIndividual()
if ptrPrincipal:IsNotNull() then
form.principal.fields[field(form.principal.fields, 'RECORD')].value =
ptrPrincipal:Clone()
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',
}
for l, f in ipairs(v.fields) do
if f.label then
local label = string.rep(' ', f.label:len()) .. ' '
local value = ' '
if f.gridDisplay or v.gridDisplay then
label = f.label .. ':'
value = fh.getParamValueForDisplay(f, true)
if value == f.label then
value = utils.choose(f.value == true, 'Yes', 'No')
end
end
f.gridLabel = iup.label {
title = label,
size = '80',
expand = 'HORIZONTAL',
}
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.active 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
local placeList = fh.createPlaceList()
s['PLAC'] = placeList
s['OCCU'] = {} -- TODO
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 then
local sVenue = pCite:getValue 'TX-CHURCH'
if not sVenue then
sVenue = pCite:getValue 'AD-ADDRESS'
end
processBirth(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 = 'Birth 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-birth-data-uk',
txtMessage,
},
},
}
iup.SetAttribute(dlg, 'NATIVEPARENT', fhGetContextInfo 'CI_PARENT_HWND') -- Set the parent window handle iup.SetHandle("main", dlg)
iup.SetGlobal('PARENTDIALOG', 'main')
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
if sType == 'principal' then
local oldRecord =
form[sType]['fields'][field(fields, 'RECORD')].value:Clone()
local oldFamily = form[sType]['fields'][field(fields, 'FAMILY')]
if oldFamily.value then
oldFamily = oldFamily.value:Clone()
else
oldFamily = fhNewItemPtr()
end
local r = fh.getParam(
'Enter ' .. sTitle,
nil,
fields,
{ 'OK', 'Cancel', fh.helpButton 'record-marriage-data-uk-principal' },
s
)
if r.ok then
form[sType].valid = 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' },
s
)
if r.ok then
form[sType].valid = true
form[sType].gridDisplay = true
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
if init then
-- first time load or new Record selected
local values, prompts = updateFamList(ptrPrincipal, 'FamilyAsChild')
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
f[field(f, 'SEX')].value = fhGetItemText(ptrPrincipal, '~.SEX')
-- f[field(f,'SEX')].protect = true
local ptrFam = f[field(f, 'FAMILY')].value
if ptrFam:IsNotNull() then
-- Set up Father of Principal if they exist
local ptrF = fhGetItemPtr(ptrFam, '~.HUSB>')
if ptrF:IsNotNull() then
local s = form['father'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrF:Clone()
s[field(s, 'RECORD')].protect = true
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'ACTION')].protect = true
end
-- Set up Mother of Principal if they exist
local ptrF = fhGetItemPtr(ptrFam, '~.WIFE>')
if ptrF:IsNotNull() then
local s = form['mother'].fields
s[field(s, 'NAME')].value = fh.editableName(
fhGetItemText(ptrF, '~.NAME:STORED')
)
s[field(s, 'RECORD')].value = ptrF:Clone()
s[field(s, 'RECORD')].protect = true
s[field(s, 'ACTION')].value = 'select'
s[field(s, 'ACTION')].protect = true
end
else
resetSection 'father'
resetSection 'mother'
end
else
resetSection 'father'
resetSection 'mother'
end
end
-- --------------------------------------------------------------- resetSection
--- Reset the section values from the master form
-- @param formSection string section index
function resetSection(formSection)
for k, v in ipairs(form[formSection]['fields']) do
for m, u in pairs(v) do
form[formSection]['fields'][k][m] = u
end
end
updateGrid()
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)
if value == f.label then
value = utils.choose(f.value == true, 'Yes', 'No')
end
end
if f.gridLabel then
f.gridLabel.title = label
end
if f.iupgrid then
f.iupgrid.title = value
end
end
end
end
function processBirth(sPlace, sAddress, sCelebrant)
local fields = {}
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')
local ptrName = fhGetItemPtr(ptr, '~.NAME')
addCitation(ptrName, 'Cited')
f.RECORD.value:MoveTo(ptr)
end
end
local ptrfamC = processParents(
data.father.RECORD.value,
data.mother.RECORD.value,
data.principal.RECORD.value
)
local eventDate = pCite:getValue 'DT-DATE'
local sPlace = pCite:getValue 'PL-LOCATION'
local sAddress = pCite:getValue 'AD-ADDRESS'
-- Create / Update Birth Event
local ptrBirth = fhGetItemPtr(data.principal.RECORD.value, '~.BIRT')
local sAction = ''
if ptrBirth:IsNotNull() then
ptrBirth, sAction = fh.createUpdateFact(
data.principal.RECORD.value,
'BIRT',
'Birth',
sPlace,
eventDate,
sAddress
)
if ptrBirth then
addCitation(ptrBirth, sAction)
end
else
ptrBirth = fh.createFact(
data.principal.RECORD.value,
'BIRT',
sPlace,
eventDate,
sAddress
)
if ptrBirth then
addCitation(ptrBirth, 'Added')
end
end
for k, f in pairs(data) do
if ptrBirth and k == 'informant' then
if f.RELATIONSHIP.value == 'Father' then
f.RECORD.value:MoveTo(data.father.RECORD.value)
f.ACTION.value = data.father.ACTION.value
end
if f.RELATIONSHIP.value == 'Mother' then
f.RECORD.value:MoveTo(data.mother.RECORD.value)
f.ACTION.value = data.mother.ACTION.value
end
if f.ACTION.value == 'name' and fh.isSet(f.NAME.value) then
fh.addWitness(ptrBirth, f.NAME.value, 'Informant')
elseif fh.isSet(f.RECORD.value) then
fh.addWitness(ptrBirth, f.RECORD.value, 'Informant')
end
end
if f.RECORD and fh.isSet(f.RECORD.value) then
if f.OCCU and f.OCCU.value:len() > 0 then
local ptrFact
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
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 = 'Added'
local deathdate = utils.choose(
data.reg.DATE.value:IsNull(),
beforeDate(eventDate),
beforeDate(data.reg.DATE.value)
)
if ptrFact:IsNotNull() then
ptrFact, sAction = fh.createUpdateFact(
f.RECORD.value,
'DEAT',
'Death',
nil,
deathdate,
nil
)
else
ptrFact = fh.createFact(f.RECORD.value, 'DEAT', nil, deathdate, nil)
end
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
)
if ptrFact then
addCitation(ptrFact, 'Added')
end
end
if
f.MARRIAGEDATE
and not (f.MARRIAGEDATE.value:IsNull())
and not (ptrfamC:IsNull())
then --create marriage event
processMarriage(
ptrfamC,
f.MARRIAGEPLACE.value,
f.MARRIAGEADDRESS.value,
f.MARRIAGEDATE.value
)
end
if
k == 'mother'
and f.RECORD.value:IsNotNull()
and fh.isSet(f.MAIDEN_NAME.value)
then
local surname = fh.getSurname(
fhGetItemText(f.RECORD.value, '~.NAME:STORED')
)
local maiden = fh.getSurname(f.MAIDEN_NAME.value)
if surname:upper() ~= maiden:upper() then
if
fh.yes(
'Update Mothers Surname from '
.. surname:upper()
.. ' to '
.. maiden:upper()
)
then
local mothersName = fhGetItemText(f.RECORD.value, '~.NAME:STORED')
mothersName = stringx.replace(
mothersName,
'/' .. surname .. '/',
'/' .. maiden .. '/'
)
local ptrName = fhGetItemPtr(f.RECORD.value, '~.NAME')
if ptrName:IsNotNull() then
fhSetValueAsText(ptrName, mothersName)
if f.ACTION and f.ACTION.value ~= 'create' then
addCitation(ptrName, 'Updated')
end
end
end
end
end
end
end
-- 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 fields['INFORMANT.RELATIONSHIP'] == 'Other' then
fields['INFORMANT.RELATIONSHIP'] = fields['INFORMANT.OTHER']
end
-- Add prefix if the maiden name field has a value
if fields['MOTHER.MAIDEN_NAME']:strip() ~= '' then
if sRegionName == 'Scotland' then
fields['MOTHER.MAIDEN_NAME'] = 'Maiden name\n'
.. fields['MOTHER.MAIDEN_NAME']
else
fields['MOTHER.MAIDEN_NAME'] = 'formerly\n'
.. fields['MOTHER.MAIDEN_NAME']
end
end
--Add prefix if residence of one or other parent is defined
if fields['MOTHER.ADDR']:strip() ~= '' then
fields['MOTHER.ADDR'] = 'at ' .. fields['MOTHER.ADDR']
elseif fields['MOTHER.PLAC']:strip() ~= '' then
fields['MOTHER.PLAC'] = 'at ' .. fields['MOTHER.PLAC']
end
if fields['FATHER.ADDR']:strip() ~= '' then
fields['FATHER.ADDR'] = 'at ' .. fields['FATHER.ADDR']
elseif fields['FATHER.PLAC']:strip() ~= '' then
fields['FATHER.PLAC'] = 'at ' .. fields['FATHER.PLAC']
end
if fields['FATHER.DECEASED']:strip() ~= '' then
fields['FATHER.OCCU'] = fields['FATHER.OCCU'] .. ' (deceased)'
end
if fields['MOTHER.DECEASED']:strip() ~= '' then
fields['MOTHER.OCCU'] = fields['MOTHER.OCCU'] .. ' (deceased)'
end
if sRegionName == 'Scotland' then
fields['PRINCIPAL.YEAR'] = dtEventDate:GetDisplayText 'YEAR'
fields['BIRTH.DAY'] = dtEventDate:GetDisplayText 'DAY'
fields['BIRTH.MONTH'] = dtEventDate:GetDisplayText 'MONTH_NAME'
fields['BIRTH.YEAR'] = dtEventDate:GetDisplayText 'YEAR'
if not form.reg.fields[7].value:IsNull() then
fields['REG.YEAR'] = form.reg.fields[7].value:GetDisplayText 'YEAR'
fields['REG.DAY'] = form.reg.fields[7].value:GetDisplayText 'DAY'
fields['REG.MONTH'] = form.reg.fields[7].value:GetDisplayText 'MONTH_NAME'
end
if fields['REG.DISTRICT']:strip() ~= '' then -- add prefix to Registration district
fields['REG.DISTRICT'] = 'at ' .. fields['REG.DISTRICT']
end
if not form.mother.fields[6].value:IsNull() then
fields['MOTHER.MARRIAGEYEAR'] =
form.mother.fields[6].value:GetDisplayText 'YEAR'
fields['MOTHER.MARRIAGEDAY'] =
form.mother.fields[6].value:GetDisplayText 'DAY'
fields['MOTHER.MARRIAGEMONTH'] =
form.mother.fields[6].value:GetDisplayText 'MONTH_NAME'
end
end
sText = fh.formatTextFromSource(templateName, templateDefault, pCite, fields)
fh.createTextFromSource(pCite, sText, 'source')
fh.outputUpdatedFields(tUpdatedFields, pCite)
end
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
function addCitation(ptr, action)
local action = action or ''
table.insert(tUpdatedFields, { ptr:Clone(), action })
pCite:appendCitation(ptr)
end
function processParents(ptrFather, ptrMother, ptrChild)
local ptrFamC = fhNewItemPtr()
local ptrFam = fhNewItemPtr()
local ptrHusb = fhNewItemPtr()
local ptrWife = fhNewItemPtr()
local bFamc = false
ptrFamC:MoveTo(ptrChild, '~.FAMC')
while ptrFamC:IsNotNull() do
ptrHusb:MoveTo(ptrFamC, '~>HUSB>')
ptrWife:MoveTo(ptrFamC, '~>WIFE>')
if
ptrHusb:IsSame(ptrFather)
and (ptrWife:IsSame(ptrMother) or ptrWife:IsNull())
then
ptrFam:MoveTo(ptrFamC, '~>')
bFamc = true
elseif
ptrWife:IsSame(ptrMother)
and (ptrHusb:IsSame(ptrFather) or ptrHusb:IsNull())
then
ptrFam:MoveTo(ptrFamC, '~>')
bFamc = true
end
ptrFamC:MoveNext 'SAME_TAG'
end
-- Check if selected people already married
if not bFamc then
local ptrChk = fhGetItemPtr(ptrFather, '~.FAMS')
local ptrWifeChk = fhNewItemPtr()
while ptrChk:IsNotNull() do
ptrWifeChk:MoveTo(ptrChk, '~>WIFE>')
if ptrWifeChk:IsSame(ptrMother) then
ptrFam:MoveTo(ptrChk, '~>')
end
ptrChk:MoveNext 'SAME_TAG'
end
if ptrFam:IsNotNull() then
fh.addFamilyAsChild(ptrChild, ptrFam)
end
end
if ptrFather:IsNotNull() or ptrMother:IsNotNull() then
if ptrFam:IsNull() then
ptrFam = fh.createFamilyAsChild(ptrChild)
addCitation(ptrFam, 'Created')
end
if fhGetItemPtr(ptrFam, '~.HUSB>'):IsNull() and ptrFather:IsNotNull() then
fh.addFamilyAsSpouse(ptrFather, ptrFam)
end
if fhGetItemPtr(ptrFam, '~.WIFE>'):IsNull() and ptrMother:IsNotNull() then
fh.addFamilyAsSpouse(ptrMother, ptrFam)
end
end
return ptrFam
end
function processMarriage(ptrFam, sPlace, sAddress, ptrDate)
if ptrFam:IsNotNull() then
local ptrMARR = fhGetItemPtr(ptrFam, '~.MARR')
local sAction
if ptrMARR:IsNotNull() then
ptrMARR, sAction = fh.createUpdateFact(
ptrFam,
'MARR',
'Marriage',
sPlace,
ptrDate,
sAddress
)
if ptrMarr then
addCitation(ptrMARR, sAction)
end
else
ptrMARR = fh.createFact(ptrFam, 'MARR', sPlace, ptrDate, sAddress)
if ptrMarr then
addCitation(ptrMARR, 'Added')
end
end
end
end
function ptrDescription(ptr)
local strDesc = ''
local strTag = fhGetTag(ptr)
if not (fhHasParentItem(ptr)) then
strDesc = 'Record (' .. fhGetTag(ptr) .. ')'
else
local strTitle = string.match(fhGetDisplayText(ptr), '([%a%w%s]*):')
if not strTitle then
strTitle = string.match(fhGetDisplayText(ptr), '(%a*)')
end
strDesc = strTitle .. ' (' .. strTag .. ')'
end
return strDesc
end
function selectOrCreate(value)
if value == 'select' then
return false, 1
else
return true, 0
end
end
function selectOrCreatePrincipal()
if value == 'select' then
return false, 1
else
-- data.principal.SEX.protect = false
return true, 0
end
end
function updateFamList(ptr)
local ptrs = { fhNewItemPtr() }
local prompts = { 'New Family As Child' }
if fh.isSet(ptr) then
local famList = fh.familyList(ptr, 'FamilyAsChild')
for i, tFam in ipairs(famList) do
table.insert(ptrs, tFam.ptr)
table.insert(prompts, tFam.label)
end
end
return ptrs, prompts
end
function field(fields, tag)
local i
for i, v in ipairs(fields) do
if tag == v.tag then
return i
end
end
end
function updateAddressList(...)
args = { ... }
print ',,,'
end
function loadMasterForms()
ptrFamily = fhNewItemPtr()
local masterForms = {}
masterForms['England and Wales'] = {
templateName = 'Birth Certificate (England and Wales).ftf',
templateDefault = [[Birth certificate {NM-PRINCIPAL} {DT-DATE}
Certified Copy of an entry of Birth given at {REG.LOCATION} Registration District {REG.DISTRICT} in sub-district of {REG.SUB} in the county of {REG.PLAC}
When and Where born | Name if any | Sex | Name and surname of Father | Name, Surname and maiden name of Mother | Occupation of Father | Signature, description and residence of informant | When Registered | Signature of Registrar | Name entered after registration
{DT-DATE}
{AD-ADDRESS}
{PL-LOCATION} | {PRINCIPAL.NAME} | {PRINCIPAL.SEX} | {FATHER.NAME} | {MOTHER.NAME}
{MOTHER.OCCU}
{MOTHER.ADDR}
{MOTHER.PLAC}
{MOTHER.MAIDEN_NAME} | {FATHER.OCCU}
{FATHER.ADDR}
{FATHER.PLAC} | {INFORMANT.NAME}
{INFORMANT.RELATIONSHIP}
{INFORMANT.ADDR}
{INFORMANT.PLAC} | {REG.DATE} | {REG.NAME} | {REG.AFTER}
]],
sections = {
reg = {
fields = {
{
tag = 'LOCATION',
type = 'STRING',
label = 'Registry',
value = 'General Register Office',
},
{
tag = 'DISTRICT',
type = 'STRING',
label = 'District',
value = '',
},
{
tag = 'SUB',
type = 'STRING',
label = 'Sub-District',
value = '',
},
{ tag = 'PLAC', type = 'STRING', label = 'County of', value = '' },
{
tag = 'NAME',
type = 'STRING',
label = 'Registrars Name',
value = '',
},
{
tag = 'AFTER',
type = 'STRING',
label = 'Name Entered After Registration',
value = '',
},
{
tag = 'DATE',
type = 'DATE',
label = 'Registration Date',
value = fhNewDate(),
},
},
title = 'Registration Information',
label = 'principal',
seq = 1,
active = true,
},
principal = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = pCite:getValue 'NM-PRINCIPAL',
minlength = 1,
protect = 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 Child' },
},
{
tag = 'SEX',
type = 'LIST',
label = 'Sex',
dr = 'SEX',
value = 'Male',
values = { 'Male', 'Female', 'Unknown' },
},
{ tag = 'BIRT', dr = 'BIRT' },
},
title = 'Principal',
label = 'principal',
seq = 2,
active = true,
gridDisplay = true,
},
father = {
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 = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = function(place)
return fh.createAddressList(place)
end,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
{ tag = 'SEX', value = 'Male' },
},
title = 'Father of principal',
seq = 3,
},
mother = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
gridDisplay = true,
},
{
tag = 'MAIDEN_NAME',
label = 'Maiden Surname',
type = 'STRING',
value = '',
gridDisplay = true,
},
{
tag = 'ACTION',
label = 'Add mother as',
type = 'LIST',
value = 'create',
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 = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = function(place)
return fh.createAddressList(place)
end,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
{ tag = 'SEX', value = 'Female' },
},
title = 'Mother of principal',
seq = 4,
},
informant = {
fields = {
{
tag = 'NAME',
label = 'Name',
type = 'STRING',
dr = 'NAME',
value = '',
minlength = 1,
},
{
tag = 'RELATIONSHIP',
label = 'Relationship',
type = 'LIST',
value = '',
values = { 'Father', 'Mother', 'Other' },
minlength = 1,
},
{
tag = 'OTHER',
label = 'Relationship (Other)',
type = 'STRING',
value = '',
},
{
tag = 'ACTION',
label = 'Add informant as',
type = 'LIST',
value = 'name',
values = { 'name', 'create', 'select' },
prompts = {
'Name Only/Parent',
'Create New Record',
'Use Existing Record',
},
child = 'RECORD',
childUpdate = selectOrCreate,
},
{
tag = 'RECORD',
label = 'Record',
type = 'RECORD',
recordtype = 'INDI',
value = fhNewItemPtr(),
protect = true,
},
{
tag = 'PLAC',
type = 'STRING',
label = 'Residence Place',
dr = 'RESI.PLAC',
value = '',
child = 'ADDR',
childUpdate = function(place)
return fh.createAddressList(place)
end,
},
{
tag = 'ADDR',
type = 'STRING',
label = 'Residence Address',
dr = 'RESI.ADDR',
value = '',
},
},
title = 'Informant',
seq = 5,
},
},
}
masterForms['Scotland'] = tablex.deepcopy(masterForms['England and Wales'])
masterForms['Scotland']['templateName'] = 'Birth Certificate (Scotland).ftf'
masterForms['Scotland']['templateDefault'] =
[[Birth {NM-PRINCIPAL} {DT-DATE}
Surname and name (if given)
Name if altered after registration| When and Where born with hour of birth| Sex| Name, surname, and rank or profession of father | Name, and maiden surname
of mother
Date and place of marriage| Signature, qualification and residence of informant,
if out of the house in which the birth occurred| When and where registered and signature of registrar
{PRINCIPAL.NAME}
{REG.AFTER}| {BIRTH.YEAR}
{BIRTH.MONTH}
{BIRTH.DAY}
{PRINCIPAL.TIME}
{AD-ADDRESS}
{PL-LOCATION}| {PRINCIPAL.SEX}| {FATHER.NAME}
{FATHER.OCCU}| {MOTHER.NAME}
{MOTHER.MAIDEN_NAME}
{MOTHER.MARRIAGEYEAR}
{MOTHER.MARRIAGEMONTH}
{MOTHER.MARRIAGEDAY}
{MOTHER.MARRIAGEPLACE}| {INFORMANT.NAME}
{INFORMANT.RELATIONSHIP}
{INFORMANT.ADDR}
{INFORMANT.PLAC}| {REG.YEAR}
{REG.MONTH}
{REG.DAY}
{REG.DISTRICT}
{REG.NAME}
The above particulars are extracted from a Register of births for the Parish of {REG.DISTRICT}
in the County of {REG.PLAC}
Given under the Seal of the {REG.LOCATION}
]]
masterForms['Scotland']['sections']['reg']['fields'][1] = {
tag = 'LOCATION',
type = 'STRING',
label = 'Registry',
value = 'Registrar General for Scotland',
}
table.insert(
masterForms['Scotland']['sections']['principal']['fields'],
6,
{ tag = 'TIME', type = 'STRING', label = 'Birth time', value = '' }
)
table.insert(
masterForms['Scotland']['sections']['mother']['fields'],
6,
{
tag = 'MARRIAGEDATE',
type = 'DATE',
label = 'Marriage Date',
value = fhNewDate(),
}
)
table.insert(
masterForms['Scotland']['sections']['mother']['fields'],
7,
{
tag = 'MARRIAGEPLACE',
type = 'STRING',
label = 'Marriage Place',
value = '',
}
)
table.insert(
masterForms['Scotland']['sections']['mother']['fields'],
8,
{
tag = 'MARRIAGEADDRESS',
type = 'STRING',
label = 'Marriage Address',
value = '',
}
)
masterForms['Ireland'] = tablex.deepcopy(masterForms['England and Wales'])
masterForms['Ireland']['templateName'] = 'Birth Certificate (Ireland).ftf'
--fields and template assumed same as E&W
masterForms['Northern Ireland'] = tablex.deepcopy(
masterForms['England and Wales']
)
masterForms['Northern Ireland']['templateName'] =
'Birth Certificate (Northern Ireland).ftf'
masterForms['Northern Ireland']['sections']['reg']['fields'][1] = {
tag = 'LOCATION',
type = 'STRING',
label = 'Registry',
value = 'General Register Office (Northern Ireland)',
}
--other fields and template assumed same as E&W
masterForms['Isle of Man'] = tablex.deepcopy(masterForms['England and Wales'])
masterForms['Isle of Man']['templateName'] =
'Birth Certificate (Isle of Man).ftf'
masterForms['Isle of Man']['sections']['reg']['fields'][1] = {
tag = 'LOCATION',
type = 'STRING',
label = 'Registry',
value = 'Civil Registry',
}
--other fields and template assumed same as E&W
masterForms['Channel Islands'] = tablex.deepcopy(
masterForms['England and Wales']
)
masterForms['Channel Islands']['templateName'] =
'Birth Certificate (Channel Islands).ftf'
masterForms['Channel Islands']['sections']['reg']['fields'][1] = {
tag = 'LOCATION',
type = 'LIST',
label = 'Registry',
value = '',
values = {
'The Superintendent Registrar',
'HM Greffier',
'The Greffier',
'The Greffe',
},
}
return masterForms
end
-------------------------------------------------------------------------------------------------------- Start Plugin
main()
Source:Record-Birth-Data-UK-5.fh_lua