Модуль:Персона

Материал из Кадровый состав НКВД 1935-1939
Перейти к: навигация, поиск

Для документации этого модуля может быть создана страница Модуль:Персона/doc

local pp = { }
local global = mw.ext.luaglobal;
local Args, Doc, Frame
tools = require( 'Модуль:Tools' )
refTools = require( 'Module:RefTools' )
local doctools = require( 'Модуль:DocTools' )
local rankTable = mw.loadData( 'Модуль:Звания' )
local abbr = mw.loadData( 'Модуль:Аббревиатуры' )
local pope = require( 'Модуль:Поиск персоны' )
global.strict( true )

local function checkDouble ( ... )
    local res, k = {}
    for i, field in ipairs( { ... } ) do
        if Args[field] and Doc.h2v[field] then
            return 'В секции {{' .. field
                .. '}} у шаблона не может быть собственного параметра «'
                .. field .. '»'
        else
            res[i] = Args[field] or Doc.h2v[field]
        end
        k = i
    end
    return nil, unpack( res, 1, k )
end

local function toRank( para )
	local z = rankTable[para.rank]
	local i = 0
	if z then
		if z.diap then
			for j, d in ipairs( z.diap ) do
				if para.cDate < d[1] then
					i = j-1
					break
				end
			end
		else
			i = 1
		end
	end

	local query = Frame:expandTemplate{ title = 'Cargo:Ranks', args = {
			nLast = para.nLast,
			nFirst = para.nFirst,
			nMiddle = para.nMiddle,
			nDisambig = para.nDisambig,
			nFull = para.nFull,
			nPrecision = para.nPrecision,
			cDate = para.cDate,
			rank = para.rank,
			subrank = i,
			canceled = para.canceled,
			origin = para.origin,
			reference = para.reference,
	        alias = para.alias,
			isVolatile = para.isVolatile,
		} }
	return query
end




pp.Main = function ( frame )
	Frame = frame
    local tmp
    local debugTxt = ''
	Args, tmp = tools.checkargs( frame:getParent().args,
        { true, true, ['дата'] = true, ['звание'] = true,  ['подразделение'] = true,
            ['должность'] = true,  ['звание+'] = true,
            ['подразделение+'] = true,  ['должность+'] = true,
            ['место службы'] = true, ['место службы+'] = true,
            ['награда'] = true, ['номер'] = true, ['подвиг'] = true,
            ['документ'] = true, ['действие'] = true, ['представление'] = true,
            ['сноска/должность'] = true, ['сноска/звание'] = true, ['сноска/награда'] = true,
            ['сноска/должность+'] = true, ['сноска/звание+'] = true,
			['в распоряжение'] = true,
            ['отмена'] = true, ['сноска'] = true, ['комментарий'] = true, } )
    if not Args then
        return tools.errorMsg( 'персона', 'Неизвестный параметр «' .. tmp .. '»' )
    end
--    local dry = mw.text.trim( frame.args[1] or '' ) == 'dry'
	local mode = frame.args.mode or ''
	local dry = mode == '-'
	local fio_precision
	if mode == '?' then
		fio_precision = '?'
	end



	Args['звание'] = doctools.abbr( Args['звание'], abbr.rank )
	Args['звание+'] = doctools.abbr( Args['звание+'], abbr.rank ) -- хотя его и не бывает
	Args['должность'] = doctools.abbr( Args['должность'], abbr.pos )
	Args['должность+'] = doctools.abbr( Args['должность+'], abbr.pos )
	Args['место службы'] = doctools.abbr( Args['место службы'], abbr.segm )
	Args['место службы+'] = doctools.abbr( Args['место службы+'], abbr.segm )


	local porno = global.get( 'porno' )
	porno = (porno or 0) + 1
	global.set( 'porno', porno )

	Doc = global.get( 'gDoc' )
	local DocAlias = global.get( 'gDocAlias' )
	if not Doc then
		return tools.errorMsg( 'персона',
			'Первым на странице должен размещаться шаблон {{ Документ }}' )
	end
	if not Doc.h2v['действие'] then
		return tools.errorMsg( 'персона',
			'Не было секции с указанием действия (присвоить звание, наградить...)' )
	end
    local noCargo = Doc.off or dry

	local prefix, fio = Args[1], Args[2]
	if not fio then
		prefix, fio = nil, prefix
	end
	if prefix then
		prefix = string.match( prefix, '^([^%.]*)[%.]?$')
		prefix = '<span class="nkvd-doc-person-number">' .. prefix .. '.&nbsp; </span>'
	else
		prefix = ''
	end
	if not fio then
		return tools.errorMsg ( 'персона', 'Не указано ФИО персоны' )
	end

	local fio_l, fio_f, fio_m, fio_d, fio_warn = tools.splitName( fio )
--	local fio_precision = nil
	if not fio_l then
		return tools.errorMsg( 'персона', fio_f )
	end
	if fio_d and ( mode == '-' or mode == '*' ) then
		return tools.errorMsg( 'персона' .. mode, 'Этот вариант шаблона не может использоваться c индексом тезки' )
	end
	if mode == '*' then
		fio = fio .. ' (*)'
		fio_d = '(*)'
	end


	local podvig = Args['подвиг']
	local podvigT
	if podvig then
		podvigT = tools.podvigLink( podvig )
	else
		podvig, podvigT = '', ''
	end

	local cargoQ = ''

	if Doc.debug then
		debugTxt = {}
		for _, h in ipairs( Doc.n2h ) do
			table.insert( debugTxt, '[' .. h .. '] = ' .. mw.dumpObject( Doc.h2v[h] ) )
		end
		debugTxt = '\n******* ' .. table.concat( debugTxt, '; ' ) .. '\n'
	end

	local canceledClass, canceledDelta, canceledBy = '', 0, Args['отмена']
	if canceledBy then
		if mw.ustring.sub( canceledBy, 1, 9 ) ~= 'Документ:' then
			canceledBy = 'Документ:' .. canceledBy
		end
		canceledClass, canceledDelta = ' nkvd-doc-canceled', -4
	end


    -- эти всегда в фиксированном месте
    local pos, unit
        = Args['должность'], Args['подразделение']
    -- звание почти всегда (кроме присвоения званий) фиксировано, можно приготовить
    local rank = Args['звание']
    if rank then
    	if rankTable[rank] then
    		if rankTable[rank].redirect then
		    	rank = rankTable[rank].redirect
		    	Args['звание'] = rank
		    end
		else
            return tools.errorMsg( 'персона',
                'Неизвестное звание «' .. rank .. '» в параметре «звание»')
		end
    end
	-- место службы — это всегда особая песня
    local segment = Doc.h2v['место службы']


    -- эти используются в общей части
    local newRank, newPos, newUnit, newSegment, actionDate
    local beforeText, newText = '', ''
    -- упоминания в приказах иной линии = 3,
    -- упоминания в приказах родной линии = 4-6,
    -- отмененные назначения =8-10,
	-- собственно отмена =11
    -- действующие назначения = 12-14
    -- для родных — тип +0 = обычное продвижение, +1 = приостановка, +2 = лишение
    local originRank, originPos = 0, 0
        -- проверяем дату. Даже если не нужна — просто чтобы не делать других проверок
    local ownDate = Args['дата']
    if ownDate then
        ownDate = tools.parseDate( ownDate )
        if not ownDate then
            return tools.errorMsg( 'персона',
                'Некорректный формат даты в параметре «дата»')
        end
        if Doc.h2v['дата'] then
            return tools.errorMsg( 'персона',
                'В секции {{дата}} у шаблона не может быть собственного параметра «дата»' )
        end
        actionDate = ownDate
    elseif Doc.h2v['дата'] then
        actionDate = Doc.h2v['дата']
    else
        actionDate = Doc.date
    end

    local statusDate = Args['представление']
    if statusDate then
	    if Doc.h2v['действие'] ~= 'наградить' then
	    	return tools.errorMsg( 'персона',
	        	'Параметр «представление» может указываться только для задания даты наградного листа' )
	    end
		statusDate = tools.parseDate( statusDate )
        if not statusDate then
            return tools.errorMsg( 'персона',
                'Некорректный формат даты в параметре «представление»')
        end
	end


--    -- сборка примечания
--	local refers = {}
--	refers[#refers+1] = Args['сноска']
--	refers[#refers+1] = global.get( 'gUniref-Документ' )  -- nil так nil
--	for _, v in pairs( Doc.n2h ) do
--		refers[#refers+1] = global.get( 'gUniref-' .. v )
--	end
--	refers = table.concat( refers, '¶' )
--	-- собрали примечание
	local referTable = {}
	local ownRef, usedRef = refTools.collect( Args, 'сноска' ), {}
	refTools.absorb( referTable, global.get( 'gUniref-Документ' ) )
	for _, v in pairs( Doc.n2h ) do
		refTools.absorb( referTable, global.get( 'gUniref-' .. v ) )
	end
	refTools.absorb( referTable, ownRef )
	if Doc.debug then
		debugTxt = debugTxt .. mw.dumpObject( referTable )
	end


	local dismissal_type, article, formula

	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  |присвоить звание|
    if Doc.h2v['действие'] == 'присвоить звание' then
		tmp, segment = checkDouble( 'место службы' )
        if tmp then
--            return tools.errorMsg( 'персона', tmp )
			segment = Args['место службы']
        end
        tmp, rank, newRank = checkDouble( 'звание', 'звание+' )
        if tmp then
            return tools.errorMsg( 'персона', tmp )
        end
        if not newRank then
            return tools.errorMsg( 'персона', 'Не задано присваиваемое звание' )
        end

        if Args['звание+'] then
			tmp = tools.db( rankTable, newRank, 'кого' )
			if not tmp then
				return tools.errorMsg( 'персона', 'Указано неизвестное звание' )
			end
            newText = ' <span class="nkvd-doc-new">— звание <b>'
                .. tmp .. '</b></span>'
        end
        originRank = 12
	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |лишить звания|
    elseif Doc.h2v['действие'] == 'лишить звания' then
		tmp, segment = checkDouble( 'место службы' )
        if tmp then
--            return tools.errorMsg( 'персона', tmp )
			segment = Args['место службы']
        end
        newRank = 'лишен'
        originRank = 14
	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |наградить|
    elseif  Doc.h2v['действие'] == 'наградить' then
		tmp, segment = checkDouble( 'место службы' )
        if tmp then
--            return tools.errorMsg( 'персона', tmp )
			segment =Args['место службы']
        end
        local prize, prizeNum
        tmp, prize = checkDouble( 'награда' )
        if tmp then
            return tools.errorMsg( 'персона', tmp )
        end
        if not prize then
            return tools.errorMsg( 'персона', 'Не указана награда' )
        end
        prizeNum = Args['номер']
        newText = ' <span class="nkvd-doc-new">'
        if Args['награда'] then
            newText = newText .. '— <b>' .. prize .. '</b>'
        end
        if prizeNum then
            newText = newText .. ' <i>[№ ' .. prizeNum .. ']</i>'
        end
        newText = newText .. '</span>'
        if not noCargo then
	        cargoQ = frame:expandTemplate{ title = 'Cargo:Prizes', args = {
				nLast = fio_l,
				nFirst = fio_f,
				nMiddle = fio_m,
				nDisambig = fio_d,
				nFull = fio,
				nPrecision = fio_precision,
	            cDate = actionDate,
	            prize = prize,
	            number = prizeNum,
	            origin = 12 + canceledDelta,
				canceled = canceledBy,
				reference = table.concat(referTable['награда'] or {}, '¶' ) .. '¶' .. table.concat(referTable.common or {}, '¶' ),
	            alias = DocAlias,
				podvig = podvig,
				isVolatile = porno,
	            } }
		end
		usedRef['награда'] = true
	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  |лишить награды|
    elseif  Doc.h2v['действие'] == 'лишить награды' then
		tmp, segment = checkDouble( 'место службы' )
        if tmp then
--            return tools.errorMsg( 'персона', tmp )
			segment = Args['место службы']
        end
        local prize, prizeNum
        tmp, prize = checkDouble( 'награда' )
        if tmp then
            return tools.errorMsg( 'персона', tmp )
        end
        if not prize then
            return tools.errorMsg( 'персона', 'Не указана награда' )
        end
        prizeNum = Args['номер']
        newText = ' <span class="nkvd-doc-new">'
        if Args['награда'] then
            newText = newText .. '— <b>' .. prize .. '</b>'
        end
        if prizeNum then
            newText = newText .. ' <i>[№ ' .. prizeNum .. ']</i>'
        end
        newText = newText .. '</span>'
        if not noCargo then
	        cargoQ = frame:expandTemplate{ title = 'Cargo:Prizes', args = {
				nLast = fio_l,
				nFirst = fio_f,
				nMiddle = fio_m,
				nDisambig = fio_d,
				nFull = fio,
				nPrecision = fio_precision,
	            cDate = actionDate,
	            prize = prize,
	            number = prizeNum,
	            origin = 14 + canceledDelta,
				canceled = canceledBy,
	            reference = table.concat(referTable['награда'] or {}, '¶' ) .. '¶' .. table.concat(referTable.common or {}, '¶' ),
	            alias = DocAlias,
				isVolatile = porno,
	            } }
	    end
		usedRef['награда'] = true
	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |назначить|
    elseif  Doc.h2v['действие'] == 'назначить' then
--1412        tmp, actionDate = checkDouble( 'дата' )
        tmp = checkDouble( 'дата' )
        if tmp then
            return tools.errorMsg( 'персона', tmp )
        end
        newPos, newUnit, newSegment, segment
            = Args['должность+'], Args['подразделение+'], segment, nil
		segment = Args['место службы'] or segment
		newSegment = Args['место службы+'] or newSegment
        if not newPos then -- 15.01.2017 or not (newUnit or Doc.revers) then
            return tools.errorMsg( 'персона',
                'Для назначения должны быть указаны должность и подразделение' )
        end
--        if not actionDate then
--            actionDate = Doc.date
--        end
        if newUnit == '=' then
            newUnit = unit
        elseif unit == '=' then
            unit = newUnit
        end
		newText = ' <span class="nkvd-doc-new">— на должность <b>' .. newPos .. '</b>'
		if newUnit then
            if unit == newUnit then
                newText = newText .. ' того же подразделения'
            else
                newText = newText .. ' в подразделении <b>' .. newUnit .. '</b>'
            end
        end
		if Args['место службы+'] then
			newText = newText .. ', ' .. tools.segment( Args['место службы+'] )
		end
        newText = newText .. '</span>'
        originPos = 12
	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |уволить|
	elseif  Doc.h2v['действие'] == 'уволить'
			or Doc.h2v['действие'] == 'уволить и лишить звания' then
		local dismissTab = mw.loadData( 'Модуль:Виды увольнения' )
--1412        tmp, actionDate = checkDouble( 'дата' )
        tmp = checkDouble( 'дата' )
        if tmp then
            return tools.errorMsg( 'персона', tmp )
        end
--        if not actionDate then
--            actionDate = Doc.date
--        end
        if not Doc.h2v['увольнение'] then
			return tools.errorMsg( 'персона',
				'Действие «Уволить» обязательно должно включать секцию «увольнение»' )
		end
		local dismissMode = Doc.h2v['увольнение'][1]

		dismissal_type = dismissTab.direction[dismissMode]
		article = Doc.h2v['увольнение'][2]
		formula = Doc.h2v['увольнение'][3]

		segment = Args['место службы'] or segment
        newPos = '-'
        newUnit = dismissTab.dirParam[dismissTab.direction[dismissMode]].unit
        originPos = 14
		if Doc.h2v['действие'] == 'уволить и лишить звания' then
            newRank = 'лишен'
        	originRank = 14
		end

	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |снять с работы|
	elseif  Doc.h2v['действие'] == 'снять с работы' then
		local dismissTab = mw.loadData( 'Модуль:Виды увольнения' )
--1412        tmp, actionDate = checkDouble( 'дата' )
        tmp = checkDouble( 'дата' )
        if tmp then
            return tools.errorMsg( 'персона', tmp )
        end
--        if not actionDate then
--            actionDate = Doc.date
--        end

		dismissal_type = dismissTab.direction['снят с работы']
		article = ''
		formula = Doc.h2v['обоснование']

		segment = Args['место службы'] or segment
        newPos = '(резерв)'
        newUnit = Args['подразделение+']
        if newUnit  then
        	newText = ' <span class="nkvd-doc-new">с направлением в <b>'
        		.. newUnit .. '</b></span>'
        end
        originPos = 14

	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |отстранить от работы|
	elseif  Doc.h2v['действие'] == 'отстранить от работы' then
		local dismissTab = mw.loadData( 'Модуль:Виды увольнения' )
--1412        tmp, actionDate = checkDouble( 'дата' )
        tmp = checkDouble( 'дата' )
        if tmp then
            return tools.errorMsg( 'персона', tmp )
        end
--        if not actionDate then
--            actionDate = Doc.date
--        end

		dismissal_type = dismissTab.direction['отстранен']
		article = ''
		formula = Doc.h2v['обоснование']

		segment = Args['место службы'] or segment
        newPos = '(резерв)'
        newUnit = Args['подразделение+']
        if newUnit  then
        	newText = ' <span class="nkvd-doc-new">с направлением в <b>'
        		.. newUnit .. '</b></span>'
        end
        originPos = 14

	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |освободить от должности|
	elseif  Doc.h2v['действие'] == 'освободить от должности' then
		local dismissTab = mw.loadData( 'Модуль:Виды увольнения' )
--1412        tmp, actionDate = checkDouble( 'дата' )
        tmp = checkDouble( 'дата' )
        if tmp then
            return tools.errorMsg( 'персона', tmp )
        end
--        if not actionDate then
--            actionDate = Doc.date
--        end

		dismissal_type = dismissTab.direction['освобожден от должности']
		article = ''
		formula = Doc.h2v['обоснование']

		segment = Args['место службы'] or segment
        newPos = '(резерв)'
        newUnit = Args['подразделение+']
        if newUnit  then
        	newText = ' <span class="nkvd-doc-new">с направлением в <b>'
        		.. newUnit .. '</b></span>'
        end
        originPos = 14

	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |отозвать|
	elseif  Doc.h2v['действие'] == 'отозвать'  or  Doc.h2v['действие'] == 'откомандировать'  then
		local dismissTab = mw.loadData( 'Модуль:Виды увольнения' )
--1412        tmp, actionDate = checkDouble( 'дата' )
        tmp = checkDouble( 'дата' ) or checkDouble( 'в распоряжение' )
        if tmp then
            return tools.errorMsg( 'персона', tmp )
        end
--        if not actionDate then
--            actionDate = Doc.date
--        end
		if Doc.h2v['в распоряжение'] then
			newSegment = Doc.h2v['в распоряжение'][2]
		end

		newSegment = Args['место службы+'] or newSegment

		if Doc.h2v['действие'] == 'отозвать' then
			dismissal_type = dismissTab.direction['отозван']
		else
			dismissal_type = dismissTab.direction['откомандирован']
		end
		article = ''
		formula = 'в распоряжение ' .. ( Args['в распоряжение'] or  Doc.h2v['в распоряжение'][1] )
		newPos = ''
		segment = Args['место службы'] or segment

		if Args['в распоряжение'] then
			newText = ' <span class="nkvd-doc-new">— в распоряжение <b>' .. Args['в распоряжение'] .. '</b>'
			if Args['место службы+'] then
				newText = newText .. ', ' .. tools.segment( Args['место службы+'] )
			end
			newText = newText .. '</span>'
		end
        originPos = 14

	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  |отменить|
	elseif  Doc.h2v['действие'] == 'отменить' then
		-- документ, действие, должность, звание, подразделение
		local cDoc = Args['документ']
		if not cDoc then
			return tools.errorMsg( 'персона',
				'Необходимо указать имя страницы отменяемого приказа' )
		end
		if mw.ustring.sub( cDoc, 1, 9 ) == 'Документ:' then
			cDoc = mw.ustring.sub( cDoc, 10, -1 )
		end
		cDoc = '[[Документ:' .. cDoc .. '|' .. cDoc .. ']]'
		local cAction = mw.ustring.lower( Args['действие'] )
		local knownAction
		if not cAction then
			return tools.errorMsg( 'персона',
				'Необходимо указать отменяемое действие («действие=уволить/'
					.. 'лишить звания/откомандировать...»' )
		end
		-- в запись-new ставится newRank c origin=originRank + canceledDelta
		-- в запись-old ставится rank с origin=originRank-8
		-- решаем систему уравнений: originRank + canceledDelta = 11
		-- originRank - 8 = 3
		-- originRank = 11, canceledDelta = 0
		if cAction == 'присвоить звание' or cAction == 'лишить звания'
				or cAction == 'уволить и лишить звания' then
			newRank = 'Отмена документа ' .. cDoc
			originRank = 11
			knownAction = true
		end
		if cAction == 'назначить' or cAction == 'уволить' or cAction == 'отстранить'
				or cAction == 'отозвать' or cAction == 'откомандировать'
				or cAction == 'уволить и лишить звания' then
			newPos = 'Отмена документа ' .. cDoc
			originPos = 11
			knownAction = true
		end
		if not knownAction then
			return tools.errorMsg( 'персона',
				'Не распознано отменяемое действие («действие=уволить/'
					.. 'лишить звания/откомандировать...»' )
		end

		beforeText = '<span class="nkvd-doc-new">' .. cDoc .. '</span> в части решения '
			.. '<span class="nkvd-doc-new">' .. cAction .. '</span>:<br>'



	-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |ой!|
	else
		return tools.errorMsg( 'персона', 'Ошибка алгоритма:'
			.. ' неизвестное действие «' .. Doc.h2v['действие'] .. '»' )
    end

 	if newRank then
        if not noCargo then
			cargoQ = cargoQ .. toRank {
					nLast = fio_l,
					nFirst = fio_f,
					nMiddle = fio_m,
					nDisambig = fio_d,
					nFull = fio,
					nPrecision = fio_precision,
					cDate = actionDate,
					rank = newRank,
					canceled = canceledBy,
					origin = originRank + canceledDelta,
					reference = table.concat(referTable['звание+'] or {}, '¶' ) .. '¶' .. table.concat(referTable.common or {}, '¶' ),
	            	alias = DocAlias,
					isVolatile = porno,
				}
		end
		usedRef['звание+'] = true
    end
	if rank then
        if newRank then
            tmp = originRank - 8
        else
            tmp = 3
        end
        if not noCargo then
			cargoQ = cargoQ .. toRank {
				nLast = fio_l,
				nFirst = fio_f,
				nMiddle = fio_m,
				nDisambig = fio_d,
				nFull = fio,
				nPrecision = fio_precision,
				cDate = statusDate or actionDate,  -- actionDate, -- а раньше было Doc.date
				rank = rank,
	            origin = tmp,
				reference = table.concat(referTable['звание'] or {}, '¶' ),
	            alias = DocAlias,
				isVolatile = porno,
			}
		end
		usedRef['звание'] = true
	end
	if newPos or newUnit or newSegment then
        if not noCargo then
			cargoQ = cargoQ .. frame:expandTemplate{ title = 'Cargo:Designations', args = {
				nLast = fio_l,
				nFirst = fio_f,
				nMiddle = fio_m,
				nDisambig = fio_d,
				nFull = fio,
				nPrecision = fio_precision,
				cDate = actionDate,
				unit = newUnit,
				segment = newSegment,
				position = newPos,
				canceled = canceledBy,
	            origin = originPos + canceledDelta,
				reference = table.concat(referTable['должность+'] or {}, '¶' ) .. '¶' .. table.concat(referTable.common or {}, '¶' ),
				dismissal_type = dismissal_type,
				article = article,
				formula = formula,
	            alias = DocAlias,
				isVolatile = porno,
				} }
		end
		usedRef['должность+'] = true
	end
	if segment == '-' then
		segment = nil
	end
	if pos or unit or segment then
        if newPos or newUnit then
            tmp = originPos - 8
        else
            tmp = 3
        end

        if not noCargo then
			cargoQ = cargoQ .. frame:expandTemplate{ title = 'Cargo:Designations', args = {
				nLast = fio_l,
				nFirst = fio_f,
				nMiddle = fio_m,
				nDisambig = fio_d,
				nFull = fio,
				nPrecision = fio_precision,
				cDate = statusDate or actionDate,  -- actionDate, -- а раньше было Doc.date
				unit = unit,
				position = pos,
				segment = segment,
	            origin = tmp,
				reference = table.concat(referTable['должность'] or {}, '¶' ),
	            alias = DocAlias,
				isVolatile = porno,
				} }
		end
		usedRef['должность'] = true
	end

	for i, _ in pairs( ownRef ) do
		if not usedRef[i] and i ~= 'common' then
			return tools.errorMsg( 'персона', 'указана сноска к незаданному параметру «' .. i .. '»')
		end
	end

	local out
	if dry then
		out = fio
	else
		out = '[[' .. fio .. ']]'
	end
	if fio_precision then
		out = out .. ' <span class="nkvd-idx"><i class="fa fa-question fa-lg">'
			.. '</i></span>'
	end
	if #fio_warn ~= 0 then
		for _, warn in ipairs( fio_warn ) do
			out = out .. ' <i class="fa fa-warning fa-lg" style="color: #f05f1a;"'
				.. ' title="' .. warn .. '"></i>'
		end
		out = out .. '[[Категория:Неаккуратные ссылки на персоналии]]'
	end
	out = prefix .. beforeText .. '<span class="nkvd-doc-fio">' .. out .. '</span>'
	if Args['звание'] then
		tmp = tools.db( rankTable, Args['звание'], 'кто' )
		if not tmp then
			return tools.errorMsg( 'персона', 'Указано неизвестное звание' )
		end
		out = out .. ', ' .. tmp
	end
	if Args['подразделение'] or Args['должность'] or Args['место службы'] then
		if Args['подразделение'] then
			tmp = { unit }
		else
			tmp = {}
		end
		if pos then
			table.insert( tmp, pos )
		end
		if Args['место службы'] then
			table.insert( tmp, tools.segment( Args['место службы'] ) )
		end
		out = out .. ' (' .. table.concat( tmp, '; ' ) .. ')'
	end
	if statusDate then

		out = out .. '<span class="nkvd-doc-statusdate" title="Звание и должность по состоянию на указанную дату">'
			.. tools.reparseDate( statusDate ) .. '</span> '
	end
	if newText ~= '' then
		out = out .. newText
	end
	if Args['дата'] then
		if Doc.h2v['действие'] == 'наградить' then
			out = out .. ' <span class="nkvd-doc-new"> — <b>'
	            .. tools.reparseDate( ownDate ) .. '</b></span>'
		else
			out = out .. ' <span class="nkvd-doc-new">c <b>'
	            .. tools.reparseDate( ownDate ) .. '</b></span>'
	     end
	end
	if porno == 800 then
		debugTxt = '[[Категория:Чересчур длинный документ]]' .. debugTxt
	end
	if referTable.common then
		debugTxt = '[[Категория:Универсальные сноски]]' .. debugTxt
	end
	if Doc.debug then
		debugTxt = debugTxt  .. mw.dumpObject( ownRef )
	end


	if dry then
		dry = 'no'
	else
		dry = ''
	end

--	global.set( 'gDoc', Doc )
	return debugTxt .. '<p class="nkvd-doc-' .. dry .. 'person' .. canceledClass .. '">' .. out .. podvigT
		.. doctools.endRecord( Args, Doc.biodoc, refTools.toline( ownRef ) )
		.. cargoQ



end
return pp