{"action":"created","issue":{"url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/issues/142","labels_url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/issues/142/labels{/name}","comments_url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/issues/142/comments","events_url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/issues/142/events","html_url":"https://github.com/GoldenSoftwareLtd/GedeminSalary/issues/142","id":107423721,"number":142,"title":"Доработки по синхронизации","user":{"login":"alexandra-gsoftware","id":11487200,"avatar_url":"https://avatars.githubusercontent.com/u/11487200?v=3","gravatar_id":"","url":"https://api.github.com/users/alexandra-gsoftware","html_url":"https://github.com/alexandra-gsoftware","followers_url":"https://api.github.com/users/alexandra-gsoftware/followers","following_url":"https://api.github.com/users/alexandra-gsoftware/following{/other_user}","gists_url":"https://api.github.com/users/alexandra-gsoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/alexandra-gsoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexandra-gsoftware/subscriptions","organizations_url":"https://api.github.com/users/alexandra-gsoftware/orgs","repos_url":"https://api.github.com/users/alexandra-gsoftware/repos","events_url":"https://api.github.com/users/alexandra-gsoftware/events{/privacy}","received_events_url":"https://api.github.com/users/alexandra-gsoftware/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/labels/Priority-High","name":"Priority-High","color":"ededed"},{"url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/labels/Server","name":"Server","color":"ededed"},{"url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/labels/Sync","name":"Sync","color":"ededed"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-09-20T23:15:53Z","updated_at":"2015-09-29T17:40:34Z","closed_at":null,"body":"Таблицы, хранящие подготовленные данные для мобильного, можно разделить на  4 категории\r\n1)Сотрудник \r\n- сотрудник (определяется ИД сотрудника)\r\n\r\n2)Расчетник\r\n- расчетник - шапка (определяется ИД сотрудника и ИД итогового)\r\n- расчетник - позиция (определяется ИД сотрудника, ИД итогового, ИД начисления, датой зачисления)\r\n- расчетник - вычеты (определяется ИД сотрудника, ИД итогового, ИД вычета, датой зачисления)\r\n- расчетник - льготы(определяется ИД сотрудника, ИД итогового, ИД льготы, датой зачисления)\r\n\r\n3)График\r\n- график - дни(определяется ИД сотрудника и датой)\r\n- график - события (определяется ИД сотрудника, датой, кодом события)\r\n\r\n4)Табель (пока нет, но будет)\r\n- табель - дни (определяется ИД сотрудника и датой)\r\n- табель - типы часов (определяется ИД сотрудника, датой, типом часов)\r\n\r\nБудем считать, что обхекты этих категорий меняются только вместе. Например, если пересчитали позицию итогового по сотруднику, нужно пересмотреть и начисления, и льготы, и вычеты.\r\n\r\nЧтобы фиксировать изменения, нужна таблица лога изменений. В ней будут следующие поля:\r\n1) номер по порядку (заполняется автоматически из генератора)\r\n2) ид сотрудника\r\n3) тип операции {0 - добавление, 1 - редактирование, 2 - удаление}\r\n4) тип объекта {1 - сотрудник, 2 - расчетник, 3 - табель}\r\n5) ид итогового начисления\r\n6) была ошибка\r\n7) описание ошибки\r\n\r\nИдентификатора самого изменяющегося объекта в логе нет.\r\n\r\nЛог заполняется на триггерах. Если в логе уже есть запись по данным сотруднику+начислению+типу объекта, то новая запись не добавляется, а апдейтится тип операции у существующей. Например, расчетник был сначала отредактрован, потом удален - в логе будет только одна запись об этом, с типом операции \"2\".\r\n\r\nМакрос синхронизации, обработав запись в логе, удаляет ее (теоретически, если возникла ошибка, запись можно оставлять, сохраняя описание ошибки)\r\n\r\nРассмотрим каждую категорию отдельно.\r\n\r\nСотрудник.\r\nДанные о сотрудниках берутся из трёх таблиц:\r\n- личная карточка USR$WG_PERSONALCARD (ФИО, личный номер)\r\n- GD_CONTACT (табельный номер)\r\n- движение сотрудника USR$WG_MOVEMENTLINE (флажок, что человек не работает)\r\n\r\nДанные о сотруднике считаются\r\n\r\n1) добавленными, если в таблице Периоды работы USR$WG_EMPLWORKTERM появляется первая (и единственная) запись по этому сотруднику;\r\n\r\n2) измененными, если\r\n  - в таблице Периоды работы появляется новая (но не единственная) запись по этому сотруднику;\r\n  - в таблице Периоды работы удаляется запись по этому сотруднику, но остаются другие записи по нему;\r\n  - в таблице Периоды работы изменяется дата увольнения;\r\n  - добавляется, удаляется запись в личной карточке;\r\n  - редактируется запись в личной карточке, меняются фио и личный номер\r\n  - редактируется табельный номер в GD_CONTACT;\r\n\r\n3) удаленными, если в таблице Периоды работы удаляется запись по этому сотруднику, и больше по нему записей не остается.\r\n\r\nТриггеры для заполнения лога будут такими:\r\n1) на USR$WG_EMPLWORKTERM, after insert or update or delete. Если инсерт или делит, и в таблице нет других записей по этому сотруднику, кроме текущей, то заносим в лог с типом операции \"добавление\" или \"удаление\", соответственно. Если есть другие записи - тип всегда \"редактирование\". Если редактируется дата увольнения, тип операции - тоже \"редактирование\".\r\n\r\n2) на USR$WG_PERSONALCARD, after insert or update or delete. Если инсерт или делит, и по сотруднику есть хоть одна запись в USR$WG_EMPLWORKTERM, заносим в лог с типом операции \"редактирование\". Если апдейт и меняются ФИО и \\ или личный номер, и есть записи в USR$WG_EMPLWORKTERM, заносим в лог с типом операции \"редактирование\". \r\n\r\n3) на GD_CONTACT, after update. Если изменился табельный номер, и есть записи в USR$WG_EMPLWORKTERM, заносим в лог с типом операции \"редактирование\". \r\n\r\nПоле \"ид итогового\" в этих триггерах, естественно, не заполняется.\r\n\r\nМакрос формирования данных для мобильного бежит по записям лога с типом \"Сотрудник\", и для каждого из этих сотрудников заново считывает данные. Если тип операции - удаление, сотрудник считается уволенным, и доступ ему закрывается.\r\n\r\nРасчетник.\r\nЗдесь все просто. Расчетник изменяется/добавляется/удаляется при соответствующих действиях в позиции итогового. Триггеры на USR$WG_TOTALLINE, after insert or update or delete. В лог заносится ид сотрудника + ид итогового начисления (по ним идентифицируется расчетник, а не по ид позиции итогового). Запросто может быть ситуация, когда тип операции по расчетнику меняется с \"удаление\" (удалили запись по сотруднику из итогового) на \"редактирование\" (заново добавили и пересчитали).\r\n\r\nЕсли позиция по расчетнику попала в лог, то будут переформированы все данные по расчетнику по этому человеку за этот месяц (шапка, начисления, вычеты, льготы).\r\n\r\nДля того, чтобы передать на мобильное факт удаления записи, добавим во все эти таблицы (шапка, начисления, вычеты, льготы) поле \"запись удалена\". Макрос синхронизации бежит по записям в логе с типом \"расчетник\". Если запись по расчетнику попала в лог, то все записи в таблицах синхронизации, связанные с этим расчетником (все начисления, вычеты, льготы) помечаются как удаленные. Дальше  считываются заново актуальные данные из таблиц зп и ок (как сейчас), и происходит insert or update в таблицы синхронизации (как сейчас). При этом флажок \"запись удалена\" обнуляется, и только реально удаленные записи остаются помеченными, как удаленные. Например, по человеку в месяц были оклад, доплата за классность, подоходный, пенсионный (эти данные уже сохранены в таблицах с подготовленной информацией для мобильного). Бухгалтер вспоминает, что внесла \"за классность\" по ошибке, и вместо классности надо внести \"за разъездной характер\". Она редактирует ручной ввод и пересчитывает человека в итоговом. В лог вносится запись по расчетнику с типом операции \"редактирование\". При синхронизации все записи в таблице расчетник - начисления (т.е. \"оклад\", \"классность\", \"подоходный\", \"пенсионный\") помечаются как удаленные. Далее находятся актуальные начисления (\"оклад\", \"разъездной характер\", \"подоходный\", \"пенсионный\"). Для каждого из актуальных начислений выполняется insert or update. Для разъездного характера срабатывает insert, для оклада, подоходного, пенсионного - update. Классность осталась помеченной, как удаленная.\r\n\r\nГрафик.\r\nСамая сложная категория для синхронизации. Почему? Потому что по человеку можед быть два типа графиков. Первичным является Календарный график. Он заполняется для конкретного человека на месяц, даже привязан к итоговому. Если Календарного графика по человеку нет, то действующим считается График рабочего времени. Этот график заполняется на год(ы) вперед, и привязывается к человеку в приказе. В итоге, может поменяться Календарный график, человек может приказом быть переведен на другой График рабочего времени, сам график рабочего времени может измениться (например, продлиться еще на год).\r\n\r\nЯ предлагаю не вести логи по графикам, а каждый раз переформировывать их, причем данные брать только за текущий месяц и следующий (если в следующем человек работает). Удаление передавать с помощью поля \"запись удалена\". Сейчас список сотрудников берется из позиций итогового, но, если график строится на будущий месяц, то позиций в итоговом может и не быть. Поэтому нужно базироваться на списке работающих сотрудников (или таблице AndroidSalaryEmployee).\r\n\r\nТабель.\r\nИх тоже два типа. Первичным считается табель мастера, запасным вариантом - вертикальный табель. К счастью, они оба привязаны к итоговому начислению. На позицию табеля мастера и на шапку вертикального табеля делаем триггеры after insert or update or delete. В лог будет попадать не ид самого табеля, а ид итогового + ид сотрудника + тип объекта-табель. В триггерах не разбираемся, сколько типов табелей есть по человеку. Изменился любой из них - запись в лог. Откуда брать данные, решает макрос синхронизации.  "},"comment":{"url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/issues/comments/144131796","html_url":"https://github.com/GoldenSoftwareLtd/GedeminSalary/issues/142#issuecomment-144131796","issue_url":"https://api.github.com/repos/GoldenSoftwareLtd/GedeminSalary/issues/142","id":144131796,"user":{"login":"alexandra-gsoftware","id":11487200,"avatar_url":"https://avatars.githubusercontent.com/u/11487200?v=3","gravatar_id":"","url":"https://api.github.com/users/alexandra-gsoftware","html_url":"https://github.com/alexandra-gsoftware","followers_url":"https://api.github.com/users/alexandra-gsoftware/followers","following_url":"https://api.github.com/users/alexandra-gsoftware/following{/other_user}","gists_url":"https://api.github.com/users/alexandra-gsoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/alexandra-gsoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexandra-gsoftware/subscriptions","organizations_url":"https://api.github.com/users/alexandra-gsoftware/orgs","repos_url":"https://api.github.com/users/alexandra-gsoftware/repos","events_url":"https://api.github.com/users/alexandra-gsoftware/events{/privacy}","received_events_url":"https://api.github.com/users/alexandra-gsoftware/received_events","type":"User","site_admin":false},"created_at":"2015-09-29T17:40:34Z","updated_at":"2015-09-29T17:40:34Z","body":"upd\r\nдоделать удаление удаленных записей из таблиц для мобильного после того, как все устройства их забрали"}}