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.