ExecutorsEdit. Реализация бизнес-объекта 'Исполнители' Назад В начало Вперед

Файл: Example\Src\VIP\Core\Executors.vip

Издание 01.2007. Добавлены директивы документирования.

Издание 01.2006. ExecutorsEdit: исправлена ошибка при обработке события cmPositionChanged.

Издание 01.2006. Действия в обработчике cmPositionChanged продублированы в cmInit, т.к. событие cmPositionChanged возникает только при смене позиции и не возникает при открытии интерфейса.

//******************************************************************************
//													(c) корпорация Галактика
// Демопроект 1.0 - Ядро приложения
// Реализация бизнес-объекта "Исполнители"
//******************************************************************************

#include IResources.vih
#include IKatPersons.vih

//******************************************************************************
#doc
 Реализация бизнес-объекта "Исполнители"
#end

interface ExecutorsEdit 'Исполнители';

create view

var
  cSuperStage : comp;   // вышестоящий этап, 0 для проектов
  dSumP	 : double; // для временного хранения суммы
  wMasterCode : word;   // код текущего владельца ресурса

as select
  PrjExecutors.*, KatPersons.*

from
  PrjExecutors, objref KatPersons,
  PrjExecutors TempPrjExecutors,
  PrjExecutors ToPrjExecutors

where	// связь "Проекты -> Сотрудники"
((
	wMasterCode			== PrjExecutors.MasterCode
  and cSuperStage			== PrjExecutors.cMaster
  and resResourceOriginal	== PrjExecutors.Status
  and PrjExecutors.cEmployee == KatPersons.NREC
))
;

//------------------------------------------------------------------------------

constructor Init;
{
  wMasterCode := 0;
  Init := true;
}

//------------------------------------------------------------------------------

constructor InitMasterCode (masterCode : word);
{
  wMasterCode := masterCode;
  InitMasterCode := true;
}

//------------------------------------------------------------------------------

#doc
  <p>В контейнере сменился текущий хозяин ресурсов.</brief>
  <p>Параметры:
  <ul>
	<li>cNewMaster - NRec нового хозяина
  </ul>
#end

procedure MasterChanged(cNewMaster : comp);
{
  cSuperStage := cNewMaster;
  ReReadRecord;
}

//------------------------------------------------------------------------------

#doc
  <p>Функция проверяет наличие ресурсов у заданного владельца.</brief>
  <p>Параметры:
  <ul>
	<li>cMaster - NRec владельца ресурсов
  </ul>
  <p>Возвращаемое значение:
  <ul>
	<li>true  - у владельца нет ресурсов
	<li>false - у владельца есть ресурсы
  </ul>
#end

function IsEmpty(cMaster : comp) : boolean;
{
  IsEmpty := (getFirst TempPrjExecutors 
			where
			((
					wMasterCode == TempPrjExecutors.MasterCode
				and cMaster	 == TempPrjExecutors.cMaster
			)) <> tsOK);
}

//------------------------------------------------------------------------------

#doc
  <p>Функция удаляет все ресурсы у заданного владельца.</brief>
  <p>Параметры:
  <ul>
	<li>cMaster - NRec владельца ресурсов
  </ul>
  <p>Возвращаемое значение:
  <ul>
	<li>true  - удаление прошло успешно
	<li>false - в противном случае
  </ul>
#end

function DeleteAll(cMaster : comp) : boolean;
{
  DeleteAll := (delete TempPrjExecutors
				where
				((
					wMasterCode == TempPrjExecutors.MasterCode
				and cMaster	 == TempPrjExecutors.cMaster
				)) = tsOK);
}

//------------------------------------------------------------------------------

#doc
  <p>Функция копирует ресурсы владельца cFrom владельцу cTo.</brief>
  Если копируемый ресурс у владельца-приемника уже есть,
  то его количество увеличивается, новая запись не создается.
  Для формирования сводной потребности используется серия вызовов -
  копирование своих ресурсов, затем - копирование ресурсов всех
  непосредственно подчиненных узлов иерархии.
  <p>Параметры:
  <ul>
	<li>cFrom   - NRec владельца, чьи ресурсы копируются
	<li>cTo	 - NRec владельца, куда ресурсы копируются
	<li>status  - вид расчета (значение поля Status)
	<li>sumP	- общая плановая стоимость ресурса
	<li>sumF	- общая фактическая стоимость ресурса
  </ul>
  <p>Возвращаемое значение:
  <ul>
	<li>true  - копирование прошло успешно
	<li>false - в противном случае
  </ul>
#end

function CopyAll(cFrom, cTo : comp; status : byte; var sumP, sumF : double) : boolean;
{
  var curStatus : byte;
  curStatus := status; // копируем расчетные данные (кроме первого обращения)
  CopyAll := true;
  sumP	:= 0;
  sumF	:= 0;

  if (cFrom = cTo)
  {
	// копирование собственных ресурсов => 1-й вызов из серии
	// => необходимо очистить остатки от предыдущего расчета
	if (delete ToPrjExecutors
		where
		((
			wMasterCode == ToPrjExecutors.MasterCode
		and cTo		 == ToPrjExecutors.cMaster
		and status	== ToPrjExecutors.Status
		)) <> tsOK)
	{
	CopyAll := false;
	exit;
}

	// при копировании собственных ресурсов исходные данные копируются
	// в расчетные => переключаем режим на копирование исходные данные
	curStatus := resResourceOriginal;
  }

  // копирование ресурсов
  _loop TempPrjExecutors
  where
  ((
		wMasterCode == TempPrjExecutors.MasterCode
	and cFrom	 == TempPrjExecutors.cMaster
	and curStatus   == TempPrjExecutors.Status
  ))
  {
	if (getFirst ToPrjExecutors
		where
		((
			wMasterCode == ToPrjExecutors.MasterCode
		and cTo		 == ToPrjExecutors.cMaster
		and status	== ToPrjExecutors.Status
		and TempPrjExecutors.cEmployee == ToPrjExecutors.cEmployee
		)) = tsOK)
	{
	// если запись по данному исполнителю уже есть, то скорректируем ее
	ToPrjExecutors.QuantP := TempPrjExecutors.QuantP + ToPrjExecutors.QuantP;
	ToPrjExecutors.QuantF := TempPrjExecutors.QuantF + ToPrjExecutors.QuantF;
	ToPrjExecutors.SummP  := TempPrjExecutors.SummP  + ToPrjExecutors.SummP;
	ToPrjExecutors.SummF  := TempPrjExecutors.SummF  + ToPrjExecutors.SummF;

	if ((update current ToPrjExecutors) <> tsOK)
	{
		CopyAll := false;
		exit;
}
}
	else
	{
	// если записи по данному исполнителю нет, то создадим новую
	ToPrjExecutors.NREC	 := 0;
	ToPrjExecutors.Status	 := status;
	ToPrjExecutors.cEmployee  := TempPrjExecutors.cEmployee;
	ToPrjExecutors.cMaster	:= cTo;
	ToPrjExecutors.MasterCode := TempPrjExecutors.MasterCode;
	ToPrjExecutors.QuantP	 := TempPrjExecutors.QuantP;
	ToPrjExecutors.QuantF	 := TempPrjExecutors.QuantF;
	ToPrjExecutors.SummP	:= TempPrjExecutors.SummP;
	ToPrjExecutors.SummF	:= TempPrjExecutors.SummF;

	if (insert current ToPrjExecutors <> tsOK)
	{
		CopyAll := false;
		exit;
}
}

	sumP := sumP + TempPrjExecutors.SummP;
	sumF := sumF + TempPrjExecutors.SummF;
  }
}

//------------------------------------------------------------------------------

browse brwPersons 'Исполнители' (,, scPrjmanPersonsEditPick);
  table PrjExecutors;

fields
  KatPersons.FIO		#3'ФИО'		 : [20], pickButton, protect;
  KatPersons.Department #3'Подразделение' : [20], pickButton, protect;
  KatPersons.Post	 #3'Должность'	 : [15], pickButton, protect;

  KatPersons.Salary	 #3'Тариф'
	('Средний дневной заработок')		 :  [6], pickButton, protect;

  PrjExecutors.QuantP   #3'Чел/дн'
	('Плановая трудоемкость, чел/дн.',,scPrjmanPersonsEdit) :  [7], noProtect;

  PrjExecutors.SummP	#3'Стоимость'
	('Плановая стоимость работы',,scPrjmanPersonsEdit)	: [10], protect;

end; // browse brwPersons;

//------------------------------------------------------------------------------

handleEvent 

cmInit:
  dSumP := PrjExecutors.SummP; // т.к. cmPositionChanged не проходит при открытии интерфейса

cmPositionChanged:
  dSumP := PrjExecutors.SummP; // необходимо запомнить цифры на случай их корректировки или удаления

cmPick:
{
  var cTmp : comp;

  if (RunInterface(C_STAFF::GetPerson, cTmp) = cmDefault)
	set PrjExecutors.cEmployee := cTmp;
}

cmUpdateRecord:
{
  PrjExecutors.SummP := PrjExecutors.QuantP * KatPersons.SALARY;

  if (update current PrjExecutors = tsOK)
	SumChanged(PrjExecutors.SummP-dSumP);
  else
	message('Ошибка при выполнении операции.' + chr(13) +
			'Повторите ввод данных.', OkButton+Error);
}

cmInsertRecord:
{
  PrjExecutors.SummP := PrjExecutors.QuantP * KatPersons.SALARY;

  if (insert current PrjExecutors = tsOK)
	SumChanged(PrjExecutors.SummP);
  else
	message('Ошибка при выполнении операции.' + chr(13) +
			'Повторите ввод данных.', OkButton+Error);
}

cmDeleteRecord:
{
  if (delete current PrjExecutors = tsOK)
	SumChanged(-dSumP);
  else
	message('Ошибка при выполнении операции.' + chr(13) +
			'Повторите удаление данных.', OkButton+Error);
}
end; // interface handleEvent

end.