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

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

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

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

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

Издание 01.2006. Ссылка на поле БД KatMaterials.PRICE заменена на более прозрачной PrjMaterials.cMaterial->PRICE. Из секций as select и from логической таблицы убрано описание табличного объекта KatMaterials.

Издание 03.2005. В интерфейсе реализации бизнес-объекта "Материалы" MaterialsEdit ссылки на поля БД KatMaterials.NAME и KatMaterials.EI заменены на более прозрачные PrjMaterials.cMaterial->NAME и PrjMaterials.cMaterial->EI. Соответственно, из логической таблицы убрана подцепка "PrjMaterials.cMaterial == KatMaterials.NREC".

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

#include IKatMaterials.vih
#include IResources.vih

//******************************************************************************
#doc
 Реализация бизнес-объекта "Материальные ресурсы"
#end

interface MaterialsEdit 'Материалы';

create view

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

as select
  PrjMaterials.*

from
  PrjMaterials,
  PrjMaterials TempPrjMaterials,
  PrjMaterials ToPrjMaterials

where
((
  // Связь: Проекты/Этапы проекта -> Материалы
	wMasterCode			== PrjMaterials.MasterCode
  and cSuperStage			== PrjMaterials.cMaster
  and resResourceOriginal	== PrjMaterials.Status
))
;

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

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

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

constructor Init;
{
  wMasterCode := 0;
  Init := 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 TempPrjMaterials
			where
			((
					wMasterCode == TempPrjMaterials.MasterCode
				and cMaster	 == TempPrjMaterials.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 TempPrjMaterials
				where
				((
				wMasterCode == TempPrjMaterials.MasterCode and
				cMaster	 == TempPrjMaterials.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 ToPrjMaterials where
		((
			wMasterCode == ToPrjMaterials.MasterCode
		and cTo		 == ToPrjMaterials.cMaster
		and status	== ToPrjMaterials.Status
		)) <> tsOK)
	{
	CopyAll := false;
	exit;
}

	// при копировании собственных ресурсов исходные данные копируются
	// в расчетные => переключаем режим на копирование исходные данные
	curStatus := resResourceOriginal;
  } // конец обработки 1-го вызова
	 
  // копирование ресурсов
  _loop TempPrjMaterials where ((
	wMasterCode == TempPrjMaterials.MasterCode and
	cFrom	 == TempPrjMaterials.cMaster	and
	curStatus   == TempPrjMaterials.Status
							 ))
  {
	if (getFirst ToPrjMaterials where ((
	wMasterCode == ToPrjMaterials.MasterCode and
	cTo		 == ToPrjMaterials.cMaster	and
	status	== ToPrjMaterials.Status	 and
	TempPrjMaterials.cMaterial == ToPrjMaterials.cMaterial
									)) = tsOK)
	{
	// если запись по данному материалу уже есть, то скорректируем ее
	ToPrjMaterials.QuantP := TempPrjMaterials.QuantP + ToPrjMaterials.QuantP;
	ToPrjMaterials.QuantF := TempPrjMaterials.QuantF + ToPrjMaterials.QuantF;
	ToPrjMaterials.SummP  := TempPrjMaterials.SummP  + ToPrjMaterials.SummP;
	ToPrjMaterials.SummF  := TempPrjMaterials.SummF  + ToPrjMaterials.SummF;

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

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

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

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

browse brwExpens 'Материалы' (,,scPrjmanMaterialsEditPick);
  table PrjMaterials;

fields

  PrjMaterials.cMaterial->NAME  #3'Наименование материала'
	('Наименование материала')							: [45], pickButton, protect;

  PrjMaterials.cMaterial->EI	#3'Ед.изм.'
	('Единица измерения')								 : [10], pickButton, protect;

  PrjMaterials.QuantP		 #3'Количество'
	('Запланированное количество',,scPrjmanMaterialsEdit) : [11], noProtect;

  PrjMaterials.SummP			#3'Стоимость'
	('Плановая стоимость',,scPrjmanMaterialsEdit)		 : [11], protect;

end; // browse brwExpens;

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

handleEvent

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

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

cmPick:
{
  var cTmp : comp;

  if (RunInterface(C_SKLAD::PickMaterials, cTmp) = cmDefault)
	set PrjMaterials.cMaterial := cTmp;
}

cmUpdateRecord:
{
  PrjMaterials.SummP := PrjMaterials.QuantP * PrjMaterials.cMaterial->Price;

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

cmInsertRecord:
{
  PrjMaterials.SummP := PrjMaterials.QuantP * PrjMaterials.cMaterial->Price;

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

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

end.