--[[ @Title: Record Burial Data (UK) @Type: Source-driven Data Entry @Subtype: "Church Register" @Author: Calico Pie @Version: 1.5 @gh: #54 #76 #112 #119 @Keywords: @LastUpdated: November 2021 @Description: Based on the Church of England Burial Register, creates burial and residence facts, and optionally a birth and/or death fact. ]] fhInitialise(7) fh = require 'fhUtils' fh.setIupDefaults() -- Local Globals local form, templateName, templateDefault local iForm = 1 local sPluginName = fhGetContextInfo 'CI_PLUGIN_NAME' local s = {} -- Autofill table local pCite -- 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 -- 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'] end if pCite:getValue 'EN-TYPE' ~= 'Burial' then -- and pCite:getValue('EN-TYPE') ~= 'Cremation' then fh.getParam(sPluginName, 'Only Burial is supported by this plugin. ') return end -- Ensure all needed fields have been completed if not ( pCite:checkRequired( 'EN-TYPE', 'NM-PRINCIPAL', 'DT-DATE', 'TX-CHURCH', 'PL-LOCATION' ) ) then fh.getParam( sPluginName, 'Not all required fields are set,\nplease ensure you have entered type, date, church, location and principal. ' ) return end -- Get form and load values from Citation 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' 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() form.principal.fields[field(form.principal.fields, 'ACTION')].value = 'select' form.principal.fields[field(form.principal.fields, 'SEX')].value = fhGetItemText( ptrPrincipal, '~.SEX' ) form.principal.fields[field(form.principal.fields, 'RECORD')].protect = false 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 = ' ' 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.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'] = fhGetDataList 'OCCUPATIONS' local addressList = {} txtMessage = iup.label { title = ' ' } 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 processDeath(pCite:getValue 'PL-LOCATION', sVenue) return iup.CLOSE else fhMessageBox 'Information has not been entered on Principal' end end btnCancel = iup.button { title = 'Cancel', padding = '4x4', expand = 'HORIZONTAL' } function btnCancel.action() return iup.CLOSE end local sTitle = 'Death 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-Death-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 r = fh.getParam( 'Enter ' .. sTitle, nil, fields, { 'OK', 'Cancel', fh.helpButton 'record-burial-uk' }, 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 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 -- --------------------------------------------------------------- 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 function processDeath(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 eventDate = pCite:getValue 'DT-DATE' local sPlace = pCite:getValue 'PL-LOCATION' local aAddress = pCite:getValue 'TX-CHURCH' local dtDeath = data.principal.DATE.value if dtDeath:IsNull() then dtDeath = eventDate:Clone() end -- Create / Update Burial/Cremation Event local sType = 'BURI' local sFactLabel = 'Burial' if pCite:getValue 'EN-TYPE' == 'Cremation' then sType = 'CREM' sFactLabel = 'Cremation' end local ptrBurial = fhGetItemPtr(data.principal.RECORD.value, '~.' .. sType) local sAction = 'Added' if ptrBurial:IsNotNull() then ptrBurial, sAction = fh.createUpdateFact( data.principal.RECORD.value, sType, sFactLabel, sPlace, eventDate, sAddress ) else ptrBurial = fh.createFact( data.principal.RECORD.value, sType, sPlace, eventDate, sAddress ) end if ptrBurial then addCitation(ptrBurial, sAction) end -- Create / Update Death Event local ptrDeath = fhGetItemPtr(data.principal.RECORD.value, '~.DEAT') sAction = 'Added' if ptrDeath:IsNotNull() then ptrDeath, sAction = fh.createUpdateFact( data.principal.RECORD.value, 'DEAT', 'Death', nil, dtDeath ) else ptrDeath = fh.createFact(data.principal.RECORD.value, 'DEAT', nil, dtDeath) end if ptrDeath then addCitation(ptrDeath, sAction) end -- Create Update Birth Event local dtBirth = fhNewDate() sAction = 'Added' if fh.isSet(data.principal.AGE.value) then dtBirth = fh.calcBirth(eventDate, data.principal.AGE.value) end if not (dtBirth:IsNull()) then local ptrBirth = fhGetItemPtr(data.principal.RECORD.value, '~.BIRT') if ptrBirth:IsNotNull() then ptrBirth, sAction = fh.createUpdateFact( data.principal.RECORD.value, 'BIRT', 'Birth', nil, dtBirth ) else ptrBirth = fh.createFact( data.principal.RECORD.value, 'BIRT', nil, dtBirth ) end if ptrBirth then addCitation(ptrBirth, sAction) end end -- Record Occupation and Residence with death date if available else use Event Date. if data.principal.OCCU and data.principal.OCCU.value:len() > 0 then local ptrFact ptrFact, sAction = fh.createFact( data.principal.RECORD.value, 'OCCU', nil, dtDeath, nil, data.principal.OCCU.value ) if ptrFact then addCitation(ptrFact, 'Added') end end if data.principal.PLAC and data.principal.PLAC.value:len() > 0 then local ptrFact, sAction = fh.createFact( data.principal.RECORD.value, 'RESI', data.principal.PLAC.value, dtDeath, data.principal.ADDR.value ) if ptrFact then addCitation(ptrFact, 'Added') 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 not (pCite:checkRequired 'AD-ADDRESS') then fields['AD-ADDRESS'] = '' end sText = fh.formatTextFromSource(templateName, templateDefault, pCite, fields) fh.createTextFromSource(pCite, sText, 'source') fh.outputUpdatedFields(tUpdatedFields, pCite) end function addCitation(ptr, action) local action = action or '' table.insert(tUpdatedFields, { ptr:Clone(), action }) pCite:appendCitation(ptr) end function selectOrCreate(value) if value == 'select' then return false, 1 else return true, 0 end 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 checksex(value) if value:IsNotNull() then local sex = fhGetItemText(value, '~.SEX') return { sex } else return { 'Male', 'Female', 'Unknown' } 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 = 'Burial (UK).ftf', templateDefault = [[{TX-CHURCH} Parish Register, {PL-LOCATION} - {EN-TYPE} {NM-PRINCIPAL} {DT-DATE} {TX-CHURCH} Date | Name and Surname | Age | Date of Death | Occupation | Residence | Signature of Celebrant {DT-DATE}| {PRINCIPAL.NAME} | {PRINCIPAL.AGE}|{PRINCIPAL.DATE}|{PRINCIPAL.OCCU}|{PRINCIPAL.ADDR} {PRINCIPAL.PLAC}| {PRINCIPAL.REG} ]], sections = { principal = { fields = { { tag = 'NAME', label = 'Name', type = 'STRING', dr = 'NAME', value = pCite:getValue 'NM-PRINCIPAL', minlength = 1, protect = true, }, { tag = 'ACTION', label = 'Add deceased 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 = 'SEX', childUpdate = checksex, }, { tag = 'SEX', type = 'LIST', label = 'Sex', dr = 'SEX', value = 'Male', values = { 'Male', 'Female', 'Unknown' }, }, { tag = 'OCCU', dr = 'OCCU', type = 'STRING', label = 'Occupation', value = '' }, { tag = 'PLAC', type = 'STRING', label = 'Residence Place', value = '', child = 'ADDR', childUpdate = address, }, { tag = 'ADDR', type = 'STRING', label = 'Residence Address', value = '' }, { tag = 'AGE', type = 'STRING', label = 'Age', value = '', mask = '(/d+[dwmyf]|full)', minlength = 0, }, { tag = 'DATE', type = 'DATE', label = 'Date of Death', value = fhNewDate() }, { tag = 'REG', type = 'STRING', label = 'Recorded by', value = '' }, }, title = 'Burial Details', label = 'principal', seq = 1, active = true, gridDisplay = true, }, }, } return masterForms end -------------------------------------------------------------------------------------------------------- Start Plugin main()