При проектировании программ кто-то использует методику Алана Купера, а кто-то считает всё это баловством. Те, кто пользуются, тоже используют её по-разному. Предлагаю посмотреть мой пример такой работы и подискутировать о том, работает это или нет.
Уточню, что сам я не являюсь проектировщиком и рассматриваю ситуацию со стороны программиста, который с переменным успехом применяет метод персон после прочтения известной книги.
Во всех компаниях, где я работал, метод персон никогда не использовался. Сталкиваюсь с ним только при выполнении разовых работ на фрилансе, поэтому я не имею представления о том, кто и как часто им пользуется на самом деле. Слышали же о нём, наверное, почти все. На Хабре есть сразу несколько статей и обзоров.
Краткая суть метода
Перед написанием кода составляется основательный проект ПО, который пишется не под сферического пользователя в вакууме, а под вымышленную персону. Персона имитирует ожидаемое поведение пользователей с двумя целями:
Отсеять нецелевую аудиторию
Не сильно привязываться к конкретному живому пользователю, мнение которого может быть предвзятым
Ну и все отмечают, что создание персон — дело запутанное. Нельзя просто так опросить пользователей и каждую их пожелашку назначить создаваемой персоне.
В том же бестселлере «Психбольница в руках пациентов» описание метода персон занимает сразу несколько глав!
Пример с беседками я выбрал потому, что нынче майские праздники и у многих шашлычно-развлекательное настроение. Также сервис аренды беседок — это сравнительно простой для понимания вид деятельности, поэтому читателю не придётся выходить за рамки статьи, чтобы изучать тонкости этой сферы предпринимательства.
На самом деле вид деятельности не такой уж и простой, но большинство из нас всё равно представляет его плюс-минус похожим образом, так что для статьи это нормальный пример.
Описанный ниже ход мыслей показывает только то, как бы я приступил к проектированию такого ПО.
Описание компании
Представим себе очень небольшую компанию с условным названием «Шашлык и точка». Её состав пусть будет таким:
Руководитель. Он же, как это часто бывает, выполняет функции маркетолога, бухгалтера и много чего ещё
Два оператора. Эти сотрудники работают с клиентами на телефоне и лично, отвечают на письма и даже взаимодействуют с компаниями-партнёрами
Четыре слесаря. Они чинят и чистят беседки, следят за чистотой вокруг них и, если нужно, встречают гостей, показывая им путь к беседке
В физическом плане компания пусть тоже не блещет размахом и сложностью:
Огороженная территория лесного массива
30 беседок разного формата
КПП при входе на территорию, где сидят операторы и руководитель
Какое-нибудь техническое помещение, где сидят слесари с кучей всяких инструментов
Бизнес-процесс предприятия гораздо важней чем то, что было описано выше, но его мы всё-таки рассмотрим чуть ниже, а пока сделаем наброски персон, чтобы перейти к сути статьи.
Вы уже поняли, раз в компании всего три должности, то и моделируемых персон тоже будет три (исключая случай, когда при проектировании мы решаем изменить бизнес-процесс и появляется новый тип сотрудника). В рамках одной должности могут работать совершенно непохожие люди, но персона будет всё равно одна. Цель этого ограничения проста — мы проектируем для сотрудника, а не для человека. Конкретный человек может через неделю уволиться и на его место придёт другой, у которого будут совсем иные предпочтения о рабочем месте. Поэтому персоной становится «универсальный солдат», который требует себе ПО, позволяющее ему идеально и непринуждённо выполнять только свои обязанности, которые общие для всех, кто будет работать на этой должности.
Куда ж без Vim-а?
Отвлечённый от шашлыков пример для наглядности.
Легендарный редактор vim имеет кучу поклонников, но не меньше и тех, кто его почему-то не любит. Условный Иван Иванович любит управление в стиле vim и если в каком-то почтовом клиенте есть такая же функциональность, он будет счастлив. Но условному Василию Васильевичу vim не нравится, поэтому он бы такую функциональность не использовал, при этом всё равно продолжал бы пользоваться электронной почтой. Отсюда следует вывод: при проектировании почтового клиента мы бы допустили ошибку, если бы проектировали его только под Ивана Ивановича или только под Василия Васильевича.
Вот начальные наброски персон, которые мы потом уточним, когда ближе познакомимся с бизнес-процессом и кандидатами:
руководитель: Малинин Семён Семёнович, 55 лет.
оператор: Горбунков Игорь Юрьевич, 30 лет.
слесарь: Жданов Пётр Николаевич, 50 лет.
Имена вымышленные и нужны для того, чтобы разработчики и менеджеры проекта могли естественным способом обсуждать действия персон и те опции, которые им нужны. Это удобней, нежели безликие "Пользователь первого типа", "Эфемерный сотрудник во-о-он тех обязанностей". Алан Купер этого не упоминает, но от себя скажу, что лучше не выбирать смешные или нетипичные имена, а также те, которые вызывают какие-то ассоциации. Например, будут нежелательны такие комбинации:
Рублёв Ибрагим Вильгельмович. У вас есть предположения о его национальности? Кто-то в штуку это обязательно спросит.
Протопопов Ферапонт Аристархович. Очень редко используемые имя и отчество, хотя настоящие и многим даже знакомые.
Емельяненко Фёдор Владимирович. Слишком сильная ассоциация со спортом, для описания бухгалтера я бы не выбрал.
Амирбабаев Бахтиёр Додахуджаевич. Идеальный вариант для ираноязычных разработчиков, но незнакомый и потому плохо запоминающийся для русских, китайцев, французов и эфиопов.
Павел Воля. Мы на работе работаем, а не шутки шутим.
Лучше выбирать привычные для вас относительно случайные имена, а затем и остальные характеристики (возраст, хронические заболевания, водительские права и всё что захотите, вплоть до размера желудка, лишь бы имело отношение к работе). Снабжение персоны деталями позволит «оживить» её и разрабатывать как для живого человека, но при этом не привязываться к конкретному лицу, делая программу неудобной всем остальным, кроме него.
Цель персоны — это понять поведение пользователя, а не хотелки отдельного представителя. Говорят, частой ошибкой является создание персоны, которая является простой комбинацией характеристик разных людей. В какой-то мере персона — это сам по себе проект, который требует усилий и времени для создания.
Бизнес-процесс организации
Руководитель работает без выходных по 12 часов в день в будние дни и редко меняется. Операторы работают по очереди графиком 2/2 и периодически увольняются, ровно как и слесари, которые работают парами и тоже 2/2.
Гости, страстно желающие отведать шашлыки на свежем воздухе, оставляют заявки либо по телефону, либо на сайте, либо придя лично. Во всех случаях они проходят через того оператора, который сейчас на смене. Он формирует заявку на беседку и сохраняет её себе, чтобы по ошибке не сдать её кому-то повторно. Он же выдаёт посетителям ключи от беседки.
После оформления заявки слесари посещают беседку, убеждаясь в её исправности (розетки/выключатели, буржуйка при наличии, скамейки, стол, мангал, двери, замки, крючки и всё-всё-всё). Обнаруженные неисправности устраняются, а окружающая территория и беседка очищаются от возможного мусора.
Кстати, предвосхищая возможные стереотипы в комментариях: отдыхающие люди — это не всегда свиньи. Я сам много раз видел, когда после отдыха после людей вообще не оставалось мусора. Уважаю таких! Но мусор на участке всё-таки появиться может — вдруг его ветер принесёт? Поэтому осмотр и очистка территории всё равно обязательны.
Если требуется, слесарь сопроводит гостей и покажет местоположение их беседки, в очередной раз убедившись в её исправности.
Руководитель занимается оплатой налогов, урегулированием споров с клиентами, выплатами зарплаты и даже иногда заменяет ушедшего в отпуск оператора.
На этом упрощённое описание бизнес-процессов пока закончим. Естественно, упущено несколько критично важных моментов, которые выходят за рамки статьи, хотя в реальности сильно влияют на проектирование (пожароохранные меры, дополнительные услуги и многое другое).
Уточнение персон и выбор ключевой из них
Узнав бизнес-процесс я, ориентируясь на логические предположения и несколько резюме с условного hh.ru, предположу портрет человека, который может работать на каждой должности. Становится ясно, что контингент очень разный и удовлетворить всех не получится, но можно выбрать «какие-нибудь» атрибуты, чтобы персоны приобрели законченный вид. В любом случае, целью является не заполнять персону второстепенными деталями, а охарактеризовать её поведение.
Ввиду того, что руководитель предприятия меняется крайне редко, а работа его непредсказуема, предположу, что его детализация вообще смысла не имеет. Поэтому рискну дополнить лишь две оставшиеся:
Горбунков Игорь Юрьевич, студент-заочник, не женат, сравнительно уверенный пользователь ПК, но даже не эникейщик. Не хочет разбираться в деталях непонятных ему процессов, смиренно относится к бюрократии.
Жданов Пётр Николаевич, предпенсионер, заядлый автолюбитель-самодельщик, ездит на работу на своём автомобиле, руки прямые и растут из нужного места, но склонен к скоропостижному увольнению при неприятных для себя обстоятельствах. Самостоятельно разбирается в неисправностях, но не будет выполнять то, что по его мнению делать не обязан.
Попробуем определить ключевую персону. Всё проектирование будет идти под эту персону и да — в каком-то смысле в ущерб остальным! Облегчить их работу с ПО можно будет на этапе реализация, не внося изменения в сам проект.
К сожалению, в нашем случае ключевая персона не очевидна:
Руководитель явно «главный», так как является бенефициаром предприятия и как никто иной заинтересован в увеличении прибыли и эффективности. С другой стороны, даже заменяя иногда оператора, он не может быть ещё и слесарем. Однако слесарей 4, а операторов всего 2. Пока непонятно. Также мне не удаётся конкретизировать эту персону, поэтому и проектировать под неё будет почти невозможно.
Оператор — центральное звено всех бизнес-процессов. Через него проходят и клиенты, и обмен заявками со слесарями, он же отчитывается руководителю об объёме работ. Если предприятие предоставляет помимо аренды ещё и дополнительные услуги (уголь, одноразовая посуда и т. п.), то их приёмку обеспечивает тоже он. Не исключено, что он же занимается и закупкой и раздачей всего этого. Не слишком ли он перегружен? Может быть его сделать ключевой персоной?
Слесарь обеспечивает — как ни странно! — лицо компании, не допуская случаев, когда гости приходят в грязные беседки с перевёрнутыми столами. Он тоже напрямую общается с клиентами, но однообразно — только в роли встречающего. Не может быть ключевой персоной? Как бы не так! Сразу ею станет, если должность оператора уйдёт на аутсорс!
А всегда ли ключевая персона однозначна?
Нет! Вариантов может быть и несколько и даже все они могут быть по-своему верными. Это означает, что выбор из возможных вариантов у нас появляется уже на уровне проектирования. Программистам эта ситуация знакома, так как мы тоже часто предлагаем несколько вариантов для решения одной и той же проблемы.
В конце нам всё же придётся сделать выбор и далее придерживаться только его. Раз пока выбор не очевиден, временно отложим его и перейдём к дополнительным инструментам, которые Алан Купер предлагает к методу персон. Их два: определение целей и сценариев.
Цели и сценарии
Начнём с руководителя. Какие у него цели? По-моему она одна — это деньги. Цель одновременно и конкретная, и очень размытая. Для меня это означает, что сделать эту персону ключевой не получится. Персона ведь должна быть достаточно простой? Слишком сложная персона потребует для себя слишком сложного проекта, который может я вообще не сумею сделать. А какие сценарии для руководителя? Их тьма, учитывая плохую формализацию и непредсказуемость его рабочих будней. Например, организация может заниматься закупками мяса, чтобы предоставлять на месте дополнительную услугу: «Маринованное мясо для шашлыков». Это на законодательном уровне требует регистрации в ГИС "Меркурий" с целью погасить входящие ВСД (не вникайте в то, что это такое, просто знайте, что это обязательно). Если есть дополнительная услуга в виде подачи/продажи бутилированной воды, то тогда компании нужно зарегистрироваться в ГИС МТ "Честный знак", так как этот товар имеет обязательную маркировку и, видимо, потребуется касса. Эти требования периодически меняются вместе с нашим законодательством, поэтому непредсказуемы. Мой итог такой: сделать руководителя ключевой персоной просто не получится — это слишком сложно.
Перейдём к оператору. Его работа тоже сложна, но в отличие от руководителя более предсказуема. При предоставлении услуг задачи следующие:
Принять заказ от клиента и назначить ему беседку
Оформить дополнительные услуги, если они нужны клиенту
Отправить к беседке слесаря
Дать слесарю расходные материалы для уборки и ремонта
Сохранить информацию об аренде во избежание двойной продажи беседки
Из этих задач мне видится такая цель оператора: отдых клиентов инцидентов и лишних проблем на его голову. Ну ведь в самом деле — какая разница оператору от деталей? В 11:00 придёт клиент, или ему удобней в 13:00? Компания ему предоставит только беседку и мангал, или ещё снабдит углём? Главное, чтобы клиент остался счастлив и не пришёл с кулаками к оператору.
Также для оператора не представляет интереса работа слесарей: то ли они розетку поменяли в беседке, то ли всю распределительную коробку, то ли замок, то ли дверь новую поставили. А может быть вообще всё было исправно и они только в этом убедились? Эти детали никак не влияют на работу оператора и являются информационным мусором.
Со слесарями всё проще: их цель вообще не вникать во что-либо, а просто получить команду привести беседку в рабочее состояние и уйти. Тут нечего проектировать, если удастся сделать их работу по принципу: «назвали беседку — пошёл работать».
Результат — предлагаю сделать ключевой персоной оператора.
В качестве неопытного проектировщика сразу предлагаю сделать интерфейс будущей программы в виде схемы или карты:
И календарь в придачу. На карте расположены беседки, по нажатию на которые можно начинать оформление заказов. На карте отсутствуют уже занятые беседки, чтобы полностью исключить возможность ошибочной двойной продажи. Кстати, карта может и не быть картой вовсе. Можно и таблицу с фильтрами сделать:
Беседка |
Отапливаемая |
Вместимость |
Цена |
№4 |
Да |
8 человек |
3000 р. |
№7 |
Нет |
8 человек |
2000 р. |
№14 |
Да |
15 человек |
5000 р. |
Но так хуже, так как в ней может оказаться такой набор данных:
Беседка |
Отапливаемая |
Вместимость |
Цена |
№10 |
Да |
8 человек |
3000 р. |
№11 |
Да |
8 человек |
3000 р. |
№12 |
Да |
8 человек |
3000 р. |
Тут три из четырёх столбцов имеют повторяющиеся значения и лишь занимают место. Гораздо лучше показывать не всё, а только фильтры, а от таблицы оставить только первый столбец. Так что от карты не сильно отличается, но карта мне нравится больше.
Важно и то, чтобы в списке не было беседок, которые сейчас на ремонте — только те, что доступны для заказа.
Карту можно ещё улучшить
При нажатии на беседку можно не только показать форму заполнения заказа, но и перерисовать некоторые детали карты:
все беседки, которые имеют вместимость меньше выбранной беседки, снабдить иконками уменьшенного размера
все беседки большего размера снабдить увеличенными иконками
Почему? Потому что люди реже выбирают между отапливаемой беседкой и неотапливаемой, но чаще выбирают между «меньше» и «больше», так как на момент заказа могут не знать точное количество тех, кто придёт. Разумеется, в этом случае не получится отображать форму заказа в модальном окне, которое перекроет нашу карту — форму нужно будет расположить рядом.
Возле карты я бы поставил крупные кнопки-фильтры:
крытая беседка
беседка с дополнительным навесом
отапливаемая
и пр. атрибуты
Переключатели достаточно интуитивны для пользователя и дают меньше когнитивного сопротивления, чем заполнение табличных форм и выпадающие списки в качестве фильтров.
При таком интерфейсе для создания заказа будет достаточно единственой кнопки «Сохранить заказ». Дополнительные данные, если они необязательные, стоит выбросить. Например, в 15-местную беседку могут прийти не 15 человек, а 14. Для компании это ненужная (в моменте, но не в перспективе!) информация, поэтому указывать это в заказе не нужно.
При сохранении заказа автоматически должно создаться уведомление для слесарей. Но они увидят его не сразу, а перед заездом гостей. Почему? Клиент может сделать заказ за неделю, а за три дня отказаться. Зачем слесарю эта информация о тех, кто хотел прийти, но передумал? Ни одного уведомления о таких клиентах — это лучше, чем целых два (о заказе и о его отмене).
При заказе с сайта нам нужны те же самые данные. Тогда логично предложить посетителю такой же интерфейс, как и оператору. А раз так, пусть работают в одном интерфейсе. Зачем разрабатывать два разных и лишний раз напрягать программистов?
Напомню, что Горбунков Игорь Юрьевич — оператор — это студент-заочник. В нашем проекте у него больше свободного времени на работе. Он сможет таскать на работу учебники и готовиться к сессии :-)
Убийство персоны
Если от Малинин Семён Семёнович (персоны руководителя) я отказался вынуждено из-за сложности, то от Жданова Петра Николаевича (персоны слесаря) мы избавились «бонусом» в результате проектирования оператора. То есть как бы убили персону. Тут появилась неочевидная проблема: слесарь является основным источником расходных материалов (розетки, лампочки, моющие средства), которые никак системой не учитываются. Но я уверен, что это нужно проектировать отдельно и с арендой самих беседок не связывать. Можно, например, попробовать самую простую готовую WMS-систему.
Обходительная программа
В книге Купера вводится термин «обходительная программа». Считается, что программа подходит под это определение, если:
интересуется мной
относится ко мне с почтением
ведет себя приветливо
обладает здравым смыслом
предугадывает мои потребности
обладает отзывчивостью
не спешит жаловаться на личные проблемы (обходительная программа всегда в курсе происходящего)
обладает проницательностью
характеризуется уверенностью в своих силах (обходительная программа концентрируется на важном)
позволяет обойти правила
поощряет незамедлительно
вызывает доверие
Честно говоря, многие из этих пунктов вызывали и всегда будут вызывать споры. Для меня это самый сложная часть проектирование и я могу долго сидеть с каждым пунктом. Как вы думаете, что можно привнести в проект, чтобы удовлетворять им? Я опишу ниже три из них.
№10. Программа позволяет обходить правила.
Какие вообще правила есть в нашем бизнесе, которые может потребоваться обойти? Например, человек произвёл оплату, но потом решил, что ему нужна беседка побольше. Он нарушил какое-то правило? С точки зрения алгоритма — конечно, ведь он ошибся в своём прогнозе. Но в проекте можно реализовать операцию «Корректировка заказа». Она позволит перенести заказ с маленькой беседки на какую-нибудь большую, а разницу в стоимости клиент оплатит отдельно. В чём плюс? В том, что не нужно делать возврат! Операция возврата — это самая отвратительная штука, которая только может быт:
её выполняют редко, поэтому как её делать сотрудники забывают очень быстро
возврат ограничивается банком
он происходит не мгновенно, а через несколько суток
Гораздо проще выставить отдельный счёт на разницу в стоимости! Если клиент сперва арендовал беседку за 3000 р., а потом решил поменять на беседку за 5000 р., то лучше выставить ему счёт на оставшиеся 2000 р. Как это сделать — программисты могут выбрать сами уже на этапе реализации. Плюсы видны сразу:
клиенту нужно выполнить лишь одну дополнительную операцию — оплату, а не две — заявление на возврат и сам возврат
выполняемые клиентом действия аналогичны новому заказу, который он совершал при первой оплате, поэтому у него уже есть опыт взаимодействия с вашим интерфейсом и никаких неожиданностей не будет, а при возврате это могла бы быть совсем другая форма
изменения вступают в силу сразу, а не по правилам банка
Из этого следует, что раз ситуация легко предусматривается уже на уровне проекта, то назвать это «обходом правил» нельзя — это вполне себе штатная ситуация.
Я придумал уж очень экзотический пример
Допустим, условный Василий оплатил беседку для 15 человек на новогодние праздники и получил на электронную почту свой билет. За несколько суток до мероприятия Василий совершает некое действие, результатом которого становится его принудительное помещение в СИЗО. Неприятная ситуация, верно? Но ведь это не повод отменять встречу в беседке остальным участникам. Оставим этичность этого процесса в стороне, ровно как и актуальность этой проблемы для самого Василия, а посмотрим на проблему поближе.
В СИЗО Василий вполне себе может попросить разрешение позвонить и — о чудо! — даже с личного телефона. Но в отделениях, как говорят, царят порядки более жёсткие, чем при проведении ЕГЭ и разрешается использовать только кнопочный телефон. С его помощью не получится переслать билет кому-то из друзей, кто всё же будет отдыхать на беседочно-шашлычном мероприятии. Настойчивые сотрудники правопорядка в СИЗО отказываются идти навстречу: «Вам и так уже многое позволили!». Тогда оператору аренды беседок поступит звонок примерно такого характера: «Я Василий, я заказал беседку, чтобы посидеть с друзьями, но теперь я сижу в СИЗО без возможности передать им билет. Пустите их без меня, пожалуйста».
Что делать оператору в этой ситуации? Если ситуацию заранее не обговаривали с руководством, то вот это и есть пример того, когда нужно обойти правила. Скорее всего, это организационный вопрос, который нужно согласовывать с руководителем.
№4. Наличие здравого смысла у программы
Это полезно при выборе даты аренды беседки. Какие существуют способы проверки того, что пользователь выбрал верную дату? А никаких. Дата берётся та, которую сам пользователь и указал. Это автоматически означает, что мы зависим от человеческой ошибки. Будет хорошо, если пользователь это заметит заранее? Как бы не так! В половине случаев пользователь перезвонит и попросит откорректировать ошибку, но в другой половине случаев пользователь позвонит со скандалом: «Я заказал беседку, а у вас произошла ошибка и дата неправильная!». То есть пользователь ошибся при вводе даты, но уверен, что не ошибся, а так как проверить это уже нельзя, то винить он будет вас. Что делать?
Можно пойти разными путями, например что-то похожее на спам в уведомлении о заказе. Раз пользователю всё равно после оплаты придёт электронный чек от банка, то отправим и мы письмо. Но какое?
Есть вероятность, что пользователь вообще не откроет письмо, поэтому можно его «заставить», отправив письмо со ссылкой, нажатие на которую подтверждает регистрацию. Если пользователь этого не сделает, то ему через полчаса придёт второе письмо об отмене аренды через ещё полчаса, если он не нажмёт эту вредную ссылку. Вероятность того, он откроет второе письмо выше, особенно если будет тема: «Отмена аренды беседки». Отменять заказ сразу после первого письма — плохая идея, ведь пользователю нужно будет снова создавать заказ с нуля. Лучше дать ему шанс этого не делать.
Альтернативное составление письма
Считается, что в субботу и воскресенье беседки арендуют чаще, чем в будние дни, а в праздничные дни — чаще, чем в субботу и воскресенье. Поэтому для этих трёх вариантов можно приготовить разные письма.
Отметим, что не важно то, как сильно три типа писем отличаются между собой. Это отличие вообще смысла не имеет: пользователь получит одно письмо, а не три, поэтому сравнивать их не в принципе не будет. Это отличает его от программиста, который заранее знает о существовании трёх видов писем.
Так как многие читают только тему письма, то ориентироваться нужно только на неё. В письме с билетом в будние дни я бы написал так: «В будний день DD.MM.YYYY вас будет ждать беседка №7». Для субботы и воскресенья так: «В выходной DD.MM.YYYY беседка №4 к вашим услугам». На праздники нужно что-то более креативное: «Ваши новогодние выходные DD.MM.YYYY пройдут в очень уютной беседке №9». Вероятность, что пользователь обратит внимание на пояснение будний/выходной выше, чем изучение какого-нибудь pdf-вложения. Можно придумать более эффективные маркеры, но оставим это вне рамок статьи.
№5. Умение предугадывать
Беседки чаще заказывают за несколько суток. За месяц до мероприятия и ранее заказывают очень редко — поменяются планы, могут и забыть. За сутки до мероприятия тоже заказывают редко, так как можно не успеть замариновать шашлыки, обсудить состав участников и т. п. В день мероприятия тоже заказывают редко, но чаще, чем за сутки, так как в этих условиях люди действуют спонтанно и целеустремлённо, а шашлыки покупают готовые.
И тут мы снова приходим к идее писем. Люди относятся к напоминанием негативно, а если уже на этапе оформления заказа мы напишем: «Мы вам напомним, чтобы вы не забыли про нас». Это немного снизит неприязнь клиента: «Хотя бы предупредили!». Также нам на руку играет то, что шашлык — это относительно редкое мероприятие и спама от него много не бывает. Это вам не магазины, которые шлют свою рекламу со всех щелей.
Для заказов, созданных сильно заранее, письма-напоминания можно отправить два раза: за 3 дня и за сутки, например. Для заказов в этот же день уведомление лучше отправить сразу: «Мы ждём вас сегодня!». Если человек ошибся с датой, у него будет шанс это сразу исправить.
Заключение
Пожалуй, напишу я такую полуCRM и выложу на GitHub. Или всё-таки проект ужасен?
Как вы используете метод персон?