воскресенье, 26 декабря 2010 г.

Синглетоны на Android. Как не стукнуться клювом об дерево...

Синглетон - объект существующий в единственном экземпляре. Удобнейшая штука для хранения объектов, существующих в течении всего времени жизни приложения: всякого рода настроек, кешей и т.д. Сильно злоупотреблять синглетонами не стоит, т.к. у них есть четко определенные недостатки. Однако в некоторых случаях без синглетонов (как и без глобальных переменных) просто не обойтись.

Синглетон можно реализовать разными способами. Обычно его реализуют так, чтобы он был доступен в любой точке приложения. Например, в виде класса, в котором все функции статические. Или в виде обычного класса со статичной функцией GetInstance() и приватным конструктором. Главное, учесть при реализации синглетона особенности языка программирования и платформы. Иначе ваше приложение рискует погрязнуть в ворохе непонятных и трудноуловимых багов. Я уже как-то писал об одной такой нетривиальной особенности реализации синглетона на CLI/C++. Оказалось, что и в реализации синглетона под Android есть подобная нетривиальная особенность.

вторник, 21 декабря 2010 г.

Расчетный счет ИП. Налоги, расходы и вычеты. Минимизация затрат.

В предыдущих статьях речь шла о тонкостях открытия валютного расчетного счета ИП, оформлении паспорта сделки и получения денег от заказчика. Теперь поговорим о насущном: во сколько обходится содержание валютного расчетного счета, какие явные и неявные траты существуют и можно ли как-нибудь сэкономить.

Первая бета Animated Widget Contact Launch на маркете.

Первая бета версия моего приложения Animated Widget Contact Launch (AWidget) появилась на Android Market.

Это - виджит, которому можно присвоить контакт из телефоной книги. Виджет отображает фотографию из свойств контакта или, если контакт без фотографии, имя.

Назначение виджета - ускорить выполнение операций с контактом. При щелчке по виджиту из него анимированно выезжает куча шариков, каждый из которых связан с той или иной функцией - позвонить, послать email, смс, отредактировать контакт и т.п.

Таким образом, любая операция с контактом выполняется в два щелчка. Плюс анимация радует глаз.

AWidget любопытен тем, что в нем использована технология анимации виджета по клику, о которой я недавно рассказывал.

Мелких багов в AWidget пока еще достаточно (это бета версия, которая требует обкатки), но в целом все работает. Плюс - AWidget полностью бесплатен.



Update: Вот Пост на 4PDA, посвященный Animated Widget Contact Launch. Со скриншотами.

Update2: сайт AWidget.

четверг, 2 декабря 2010 г.

Анимированный виджет на Android. Анимация по клику.

Итак, анимированный виджет на Android сделать толком не получается. Идем в обход?

Идея проста. Делаем виджет. При нажатии на виджет появляется активити. Активити полностью прозрачна и целиком перекрывает рабочий стол. В том месте, где на рабочем столе расположен исходный виджет, на активити рисуем такой же "виджет". И уже этот "виджет" мы можем сделать анимированным.

Практика показала, что такой подход действительно работает. Но в нем много нюансов. О них и пойдет речь.

четверг, 18 ноября 2010 г.

Анимированный виджет на Android и setImageViewUri

В прошлый раз, обсуждая возможность создания анимированного виджета на Android, я остановился на прискорбном выводе: виджет с динамически генерируемой анимацией создать не получается. Если картинки для анимации сидят в ресурсах - тогда другое дело, функция setImageViewResource отрабатывает бодро. А вот пересылка в remoteview битмапок через setImageViewBitmap по несколько раз в секунду приводит к катастрофическому проседанию FPS и ошибкам FAILED BINDER TRANSACTION. Остался открытым вопрос - что если для обновления виджета применить функцию setImageViewUri? Попробуем.

среда, 17 ноября 2010 г.

Исходные коды для блога на google code

Наконец то решил для себя вопрос, где хранить исходные коды мелких проектов, которые я создаю для блога. Решил тривиально - завел на google code новый проект dvsrc. Теперь буду заливать все исходники туда и для каждого создавать короткое wiki-сообщение на английском языке. Исходники будут подразделяться на группы C++, C#, Delphi, Android и т.д. Надеюсь, будет удобно и мне, и читателям.

суббота, 13 ноября 2010 г.

воскресенье, 7 ноября 2010 г.

Борьба за килобайты. Компактность VC++-приложения

Собрав первый снапшот плагина NamedFolders я обнаружил, что размер итогового бинарного файла вырос с 380 до 700 кб. В два раза(!) больше. При том, что я всего лишь сменил компилятор с VC2005 на VC2008 и внес небольшие изменения в код. Более того. Размер новой, 64-битной версии плагина зашкаливает за 1 Mb. Для плагина FAR это уже через-чур. Как уменьшить размер итоговой dll? Решил разобраться.

вторник, 19 октября 2010 г.

Named Folders 3.0. Первый снапшот

Выложил первый снапшот Named Folders 3.0. Основные изменения: рефакторинг и чистка кода, перевод плагина на FAR API 2.0 и юникод, выпуск 64-битной версии.

воскресенье, 17 октября 2010 г.

Перевод плагина на FAR 2.X

В FAR API 2.X был внесен ряд серьезных изменений, по сравнению с FAR API 1.X. Все подробности изложены в Encyclopedia for Developers. Я же хочу рассказать о тех изменениях, с которыми я столкнулся при переводе плагина Named Folders на FAR API 2.X.

суббота, 16 октября 2010 г.

Как запустить ярлык 64-битного приложения из 32-битного через ShellExecute.

В плагине FAR Named Folders (NF) есть полезная функция - запуск приложения из меню "Пуск". Набираете в командной строке команду "cs:a" и вам показывается список приложений, названия которых соответствуют маске "*a*". В Win7 меню "Пуск" было модернизировано, в нем появился подобный фильтр, но лично мне через Far программы запускать по-прежнему гораздо быстрее. К сожалению, после перехода на 64-битную версию Win7, я обнаружил, что некоторые приложения запускаться через NF перестали.

Расследование показало, что возникла проблема с запуском 64-битных приложений из 32-битного FAR. В NF запуск приложений реализован через функцию ShellExecute - через нее запускается ярлык (LNK-файл) приложения, хранящийся в меню "Пуск". Выяснилось, что ShellExecute, вызванная из 32-битного приложения, ярлыки 64-битных приложений обрабатывает неправильно.

четверг, 14 октября 2010 г.

Программирование под Android. С чего начать.

Появилась необходимость написать проект под Android. Засел за гугл и пару дней шерстил интернет на предмет полезной информации. Вот результаты.

среда, 13 октября 2010 г.

Как подружить BOOST_FOREACH с контейнером без "iterator"

В библиотеке stlsoft есть полезный класс
winstl::findfile_sequence_w, который оборачивает вызовы системных функций FindFirstFileW, FindNextFileW в STL-контейнер. С его помощью перебор файлов реализуется так:
#include <winstl/filesystem/findfile_sequence.hpp>
using namespace stlsoft;
using namespace winstl;

findfile_sequence_w seq(L"c:\", L"*.*", findfile_sequence_w::files); 
findfile_sequence_w::const_iterator p = seq.begin();
while (p != seq.end()) {
   std::wstring filename = (*p).get_filename();
   ++p;
}
Чтобы сделать код более компактным, можно применить BOOST_FOREACH:
findfile_sequence_w seq(L"c:\", L"*.*", findfile_sequence_w::files); 
BOOST_FOREACH(findfile_sequence_w::value_type const& t, f) {
   std::wstring filename = t.get_filename();
}
Но здесь ожидает неприятный сюрприз: BOOST_FOREACH требует наличие двух типов итераторов: iterator и const_iterator. В findfile_sequence_w является псевдо-STL-контейнером - типа "iterator" в нем нет.

Не беда. Функциональность BOOST_FOREACH предусматривает возможность расширения на случай использования нестандартных коллекций.
Так что можно заставить BOOST_FOREACH использовать "const_iterator" вместо "iterator":
#include <boost/foreach.hpp>
namespace boost { 
/*possibility to use BOOST_FOREACH with findfile_sequence_w;
findfile_sequence_w doesn't contain "iterator", it contains only "const_iterator"*/
  template<>
  struct range_mutable_iterator {
      typedef winstl::findfile_sequence_w::const_iterator type;
  };
}
...
BOOST_FOREACH(findfile_sequence_w::value_type const& t, f){}
//or, with same result:
BOOST_FOREACH(findfile_sequence_w::value_type & t, f){}
Поскольку в findfile_sequence_w все функции константные, вреда от такой подмены не будет, а BOOST_FOREACH заработает как надо.

четверг, 7 октября 2010 г.

Подводные камни google code: ваш email открыт для всех.

Прошло чуть больше недели, как я создал на google code проект Named Folders. Все шло хорошо, а сегодня я вдруг осознал, что название моего google-аккаунта лежит в открытом доступе... Его видно в issues, его видно в svn. Это значит, что мой email запросто могут заспамить.

Как это не печально, никнеймов на google code нет. Политика у них такая.

Пришлось повозиться и переключить проект на альтернативный аккаунт. Для этого сделал repository reset (естественно, пропала вся история ревизий) и пересоздал все issues.

Самое печальное, что в issues видны аккаунты тех, кто эти issues создавал. Кроме того, если у вас нет google аккаунта, то issue вы создать не сможете. В результате, польза от такого багтрекера весьма и весьма ограничена.

Так что у google code есть серьезные недостатки..

Update: из-за вот этого бага (фичи?) переключение проекта на альтернативный аккаунт не решило проблемы :(

воскресенье, 3 октября 2010 г.

Каждому списку - по фильтру.

Вам приходилось сталкиваться с программами, в которых значение поля выбирается из длинного списка, а поиска по списку не предусмотрено? Работать с такими программами - сущее мучение. Всегда снабжайте списки средствами быстрого поиска. Ваши пользователи скажут вам большое спасибо.

Одним из вариантов такого поиска является динамическая фильтрация списка по ключевым словам. Динамическая - значит налету, прямо в процессе ввода ключевых слов пользователем. Скажем, у вас есть список сотрудников, в котором отображаются: идентификатор, ФИО, год рождения, адрес. Вы набираете "77 кр". Список сокращается. В нем остаются только те сотрудники, в данных у которых встречаются число 77 и/или слово "кр". Например, с сотрудники с фамилиями "Кравцов", "Окрошкин", проживающие на улице "Крапивина", с почтовым индексом 667770, с 1977 годом рождения, c идентификаторами 77, 777, 6772 и т.п. Поиск может осуществляться по принципу '77 ИЛИ кр' или '77 И кр' - как удобнее.

Подобный способ фильтрации хорош тем, что практически любая информация, известная пользователю, быстро приведет его к нужной записи в списке. Причем приведет быстро, за пару секунд. Главное, чтобы необходимая информация в списке была.

Конечно, можно сделать специальную форму поиска с четырьмя полями: ФИО, адрес, год рождения, идентификатор. Да еще поместить ее в отдельное окно. Можно.. Но зачем? Такие формы оправданы только в случае больших массивов данных, когда поиск ведется с помощью SQL-запросов и для ускорения поиска используются индексы по полям таблиц базы данных. Если же список целиком сидит в памяти (десяток, сотня, несколько тысяч строк), то достаточно одной строки поиска, которая легко помещается рядом со списком. Согласитесь, что место для одного дополнительного поля ввода над/под списком выделить можно всегда.

Теперь о реализации такого фильтра на Delphi. Здесь два важных момента. Во-первых, фильтр должен прикручиваться к любой форме буквально одной-двумя строками кода. Тогда его будет удобно использовать. Во-вторых, фильтр должен быть ориентирован на работу TDataSet, т.к. именно этот класс (и его наследники) используется для хранения списков в клиентских приложениях для работы с базами данных.

Для себя я реализовал такой фильтр в виде модуля FastFilter. Делать отдельный компонент я не стал - фильтр должен годится и для приложений, использующих не только стандартный TEdit, но и сторонние компоненты ввода.

Чтобы прикрутить фильтр к форме достаточно создать экземпляр класса
TFastFilterCommon:
TForm1 = class(TForm)  
  ...  
  private    
   m_F: TFastFilterCommon;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin 
  m_F := TFastFilterCommon.Create(  
    editFilter //поле ввода фильтра  
    , dataSetToFilter //фильтруемый DataSet  
    , false //'a b' означает 'a ИЛИ b' (а не 'a И b') 
  ); 
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin  
  m_F.Free;
end;
Фильтрация будет вестись по всем полям DataSet. Если нужна фильтрация только по выбранным полям, то нужно перечислить эти поля в конструкторе:
m_F := TFastFilterCommon.Create(  
  editFilter //поле ввода фильтра  
  , dataSetToFilter //фильтруемый DataSet  
  , ['Name', 'Surname', 'Address'] //поля для фильтрации
  , false //'a b' означает 'a ИЛИ b' (а не 'a И b') 
); 
Класс содержит внутренний таймер, определяющий задержку между завершением ввода и началом фильтрации. Пользователь набрал слово, прошло 0.2 сек, если пользователь ничего больше не нажимает, начинается фильтрация. Если пользователь не хочет ждать, он может нажать Ctrl+Enter и фильтрация начнется мгновенно.

В фильтре работают клавиши Up и Down. Они позволяют перемещаться по датасету не выходя из поля ввода.

Модуль FastFilter содержит два класса: TFastFilter и TFastFilterCommon. Первый содержит только статические функции, которые реализуют необходимые обработчики в общем виде. Второй заточен под стандартный TEdit. Если используется нестандартный вариант TEdit, то потребуется создать дополнительный класс TFastFilterXXX (или вызывать функции TFastFilter прямо из формы).

Важное ограничение: FastFilter предполагает, что все данные, по которым нужно вести фильтрацию, содержатся в отображаемом на экране DataSet. Но так бывает далеко не всегда. Пример - фильтрация списка клиентов по номерам телефонов. Номера телефонов хранятся, естественно, в другом DataSet, отдельно от списка клиентов, т.к. у каждого клиента может быть по несколько телефонов. В подобных случаях стандартный TFastFilterCommon потребует доработки.

Исходные коды FastFilter и демонстрационного приложения.

Browse source codes,
download source codes, view short description in English.

понедельник, 27 сентября 2010 г.

Named Folders 3.0 (alpha) на GoogleCode.

Давным давно, в 2002 году, я написал плагин Named Folders для быстрого перемещения между директориями в Far Manager. Плагин оказался достаточно удачным и востребованным, несколько лет я его дорабатывал и оттачивал. Правда последние годы я его не трогал, хотя использую ежедневно. Плагин делает все что мне нужно - чего его трогать.. Сообщения о мелких багах мне, конечно, присылали. Что-то я правил, что-то - складывал на полку - дойдут руки когда-нибудь.

Но сейчас, похоже, пришло время доработать плагин. Необходимость обусловлена двумя факторами: выходом юникодного Far 2.0 и ростом популярности 64-битных систем. Как не крути, нужен Named Folders x86/x64 для Far 2.0. И я решил доработать плагин и, заодно, привести проект в порядок.

Основные задачи при разработке Named Folders 3.X следущие:
  • портировать исходные коды под Far API 2.0;
  • обеспечить возможность компиляции 64-битной версии плагина;
  • провести глобальный рефакторинг кода и заменить русские комментарии английскими;
  • поправить известные баги;
  • реализовать новый функционал, который стал возможен под Far 2.0;
  • преобразовать Named Folders в open source проект;
  • добиться того, чтобы проект компилировался не только под Visual C++, но и под другими компиляторами.
Я разместил проект namedfolders на GoogleCode. Так что теперь у плагина есть issues трекер, wiki и открытый репозиторий svn. Исходные коды релизов плагина были открыты всегда, но теперь будет доступ и к промежуточным версиям. Wiki, я надеюсь, даст мне более удобный способ вести документацию плагина. Ну а issues трекер более не позволит мне забыть об имеющихся багах, так что обо всех багах просьба писать именно в issues.

Текущая версия плагина в репозитории пока еще очень сырая. Как минимум, не работают диалоги. Но я постараюсь не слишком тянуть с первым релизом.

Если у вас есть пожелания по дальнейшему развитию плагина - пишите.

Update: с issues не все так просто...

четверг, 23 сентября 2010 г.

Расчетный счет ИП. Паспорт сделки и процесс получения денег от зарубежного заказчика.

Про тонкости открытия расчетного счета и составления договора с клиентом я написал ранее. Одновременно с открытием счета вы получаете от банка доступ к системе банк-клиент. Через нее ведется вся дальнейшая работа со счетом. Даже паспорт сделки уже оформляется через банк-клиент.

Каких-то особых сложностей при оформлении паспорта сделки мне не встретилось. Потребовалось указать личные данные - ФИО, адрес, ОГРН, ИНН, - и ввести информацию о договоре с клиентом - номер, дату подписания договора, дату завершения договора. Поскольку точной суммы договора у меня не было, то вместо суммы я указал "б/с" (без суммы).

У паспорта сделки есть уникальный номер. Номер присваивается в банке. Уж не знаю, то ли это особенности банк-клиента моего банка, то ли стандартная практика, но через банк-клиент этот номер я посмотреть нм могу. Между тем, его нужно вписывать в справку о валютной операции. Когда пришел первый платеж, мне пришлось оперативно съездить в банк, взять подписанный паспорт сделки в бумажном виде и посмотреть номер там.

После оформления паспорта сделки можно, наконец, получить от клиента первый платеж. Деньги от клиента поступают по следующей схеме:
  1. вы выставляете клиенту счет;
  2. клиент переводит деньги на ваш транзитный счет;
  3. деньги поступают в банк на ваш транзитный счет, вам поступает уведомление о поступлении платежа;
  4. вы отправляете копию инвойса в банк;
  5. вы заполняете справку о валютной операции и даете распоряжение о переводе денег с транзитного счета на текущий;
  6. валютный контроль проводит проверку, берет небольшую мзду; после этого деньги поступают на ваш текущий валютный счет;
  7. вы продаете валюту с текущего валютного счета на расчетный рублевый счет;
  8. вы переводите деньги с расчетного рублевого счета себе на карточку.
Первое что нужно сделать - выставить клиенту счет или, в банковской терминологии, инвойс. По поводу инвойса в банке мне сказали следующее. Инвойс составляется в произвольной форме, но с обязательным указанием следующих реквизитов:
  • наименование организации выставляющей счет (вы);
  • наименовании организации на чьё имя счет выставлен (ваш контрагент);
  • наименование оплачиваемой услуги (например, "software development");
  • период или расчетная единица (например, количество отработанных часов);
  • стоимость одной расчетной единицы (стоимость часа работы);
  • общая сумма;
  • ссылку на договор по которому выставлен счет
  • реквизиты сторон - желательны но не обязательны (т.к. указан договор).
Кроме того, в инвойсе нужно написать магическую фразу "Без НДС". Инвойс может быть англоязычным, однако если он будет содержать слишком много профессиональных терминов, то может потребуется перевод. Инвойс должен быть подписан (вами) и на нем должна стоять печать (ваша, если она у вас есть). Прилагаю образец инвойса, который получился у меня.

Перевод денег занимает порядка 3 рабочих дней. Первое, что нужно сделать после поступления денег, составить справку о валютной операции. Сделать это нужно в течении 7 рабочих дней со дня поступления денег (с 2011 года - в течении 15 дней). Справка составляется достаточно просто. В справке вы указываете:После создания справки вы должны отдать распоряжение о перечислении денег с транзитного счета на текущий. Справка и распоряжение должны быть датированы одной датой и составляются одновременно. В распоряжении указывается номер справки.

Кстати, банку требуется копия инвойса. В моем банке меня попросили загружать инвойс в систему банк-клиент по факту поступления денег. Поэтому при поступлении платежа я делаю три операции: загружаю инвойс, создаю валютную справку, создаю распоряжение о переводе денег на текущий валютный счет.

После поступления денег на текущий счет, можно перевести их на рублевый и, далее, использовать по своему усмотрению. Например, перевести их на свою пластиковую карточку, указав в назначении платежа - "пополнение личных средств". Банк не берет проценты за такой перевод, и снять таким образом можно до 200 тыс. руб. в месяц (в других банках условия могут быть иными).

Осталось обсудить два вопроса: во сколько все это удовольствие обходится и как платить налоги.

Update: почитайте, какие жесткие последствия могут быть при нарушении валютного законодательства. Как минимум, для ООО.

вторник, 21 сентября 2010 г.

Актуальный анекдот из "Age of Turbulence"

Читая увлекательную книгу "Age of Turbulence" Алана Гринспана наткнулся на анекдот, который автору рассказал президент Рейган. Не могу удержаться от "перепоста":

"Леонид Брежнев принимает парад войск на красной площади. Мимо него проходят все советские войска. Вначале идут блестящие батальоны элитной пехоты, все солдаты как на подбор. Далее едут грозные танки и артиллерия. Провозят ядерное оружие, демонстрирущее всю мощь великой державы... А самоей последней вдруг проходит группа каких-то мужичков, явно гражданских - плохо выбритых, в помятой одежде, шагающих в разнобой и очень сильно не соответствующих моменту.

Помощник подбегает к Брежневу и начитает извиняться:
- Товарищ Брежнев, мои извинения, я не знаю кто эти люди и что они делают на параде.
- Не беспокойтесь, товарищ, - отвечает Брежнев. - Это я их пригласил. Это наши экономисты. Вы даже не представляете, насколько разрушительными они могут быть..."

P.s. вот здесь этот анекдот приведен на английском.

Update а вот видео в тему:
Reagan tells Soviet jokes,
Reagan tells Soviet jokes, pt .2, President Reagan - his humor and wit

пятница, 10 сентября 2010 г.

Критические секции с таймаутом в Delphi

Критические секции с таймаутом очень удобны при отладке приложений. В случае возникновения блокировки срабатывает таймаут, и вылетает исключение, позволяющее легко определить где именно произошла блокировка.

Стандартные критические сеации таймауты не поддерживают - секции с таймаутом нужно реализовывать самостоятельно. На RSDN есть отличная статья на эту тему - Критические секции. В ней приведен вариант реализации критических секций с таймаутом (см. листинг 14). Код дан на С++. Я портировал этот код на Delphi и, на его основе, реализовал класс TCriticalSectionDbg. Этот класс можно использовать при отладке вместо TCriticalSection (замену удобно проводить с помощью директив условной компиляции). Выкладываю исходные коды. Если вы обнаружите в них ошибку, пожалуйста сообщите о ней в комментариях, буду очень признателен.

К исходникам TCriticalSectionDbg приложен тестовый проект на Delphi 2010, демонстрирующий блокировку потоков, а так же аналогичный С++-ный проект (можно сравнивать результаты работы функций построчно). Мне этот проект потребовался при портировании вызова функции InterlockedCompareExchangePointer, который в Delphi оказался несколько, гм.. нетривиален.

Скачать исходные коды TCriticalSectionDbg.

четверг, 9 сентября 2010 г.

Открытие валютного расчетного счета индивидуальным предпринимателем

Как легально работать с заграничными клиентами - проблема, актуальная для многих программистов. Не так давно на хабре была опубликована статья Как легально получать деньги из-за пределов России, где этот вопрос рассмотрен детально. Крайне полезная статья. Тем не менее, в ней опущены некоторые тонкости, порой незначительные, но вызывающие вопросы на практике. Попробую восполнить ряд пробелов исходя из личного опыта.

Для открытия расчетного счета требуются нотариально заверенные копии следующих документов: свидетельство о регистрации ИП, ИНН, информационное письмо органа государственной статистики об учете в ЕГРПО, выписка из ЕГРИП. При открытии двух счетов (рублевого и валютного) с меня потребовали один пакет документов.

Вы открыли два счета - рублевый и валютный. Теперь у вас есть три счета: расчетный рублевый счет, текущий валютный счет и транзитный валютный счет.

Первое что нужно сделать - уведомить об открытии счета налоговую, пенсионный фонд (ПФ) и фонд социального страхования (ФСС) (Update: ФСС нужно уведомлять только если у вас есть наемные работники). Сделать это нужно в течении 7 дней (см. пункт 3 статьи 28 Федерального закона от 24.07.2009 #212-ФЗ и пункт 2 статьи 23 Налогового кодекса РФ). Соответственно, нужно составить по три уведомления для каждого счета, каждое в двух экземплярах. Т.е. у вас должно быть 2 * 3 * 2 = 12 уведомлений. Один экземпляр вы отдаете, другой оставляете себе. Кстати: 7 дней - это семь рабочих дней. Дата открытия счета указана в справке, которую вам выдают в банке.

Форма уведомления для налоговой есть в программе Налогоплательщик ЮЛ. Только имейте ввиду, что форма там может в любой момент измениться, поэтому всегда используйте свежую версию программы. Лично я сделал уведомление по образцу предыдущего года, пришел в налоговую и меня с ним, естественно, завернули. Ходил второй раз.

Уведомления для ФСС РФ и ПФ РФ лежат в интернете: форма уведомления для ФСС РФ и форма уведомления ПФ РФ.

Внимание: в уведомлении об открытии валютного счета указывается номер текущего валютного счета (не транзитного!). И еще: если у вас есть печать, то не забывайте ставить ее на уведомлениях.

Следующий шаг - заключение договора с заказчиком. В нашем случае, со стороны банка к договору предъявлялись следующие требования: договор составляется на двух языках (в две колонки: слева на русском, справа на английском), из договора должна быть понятна максимальная сумма, которая может быть получена в рамках договора и максимальные сроки выполнения.

Мы успешно применили прием, описанный в указанной выше статье - "Если оплата планируется периодически, а делать акты о выполненных работах каждый раз нет желания, то нужно добавить [ключевую] фразу".

В нашем случае "ключевая" фраза прозвучала так:Заказчик перечисляет Исполнителю по настоящему Договору ежемесячный аванс на расчетный счет Исполнителя на основании выставленного счета в размере, определенном Сторонами на основании отчета Исполнителя о количестве затраченные часов на разработку Программного обеспечения. Окончательный расчет по Техническому заданию Заказчиком производится на расчетный счет Исполнителя, на основании счетов выставленных Исполнителем, в срок не позднее 15 (пятнадцати) календарных дней с момента подписания Сторонами Акта приема-передачи по данному Техническому заданию.

То же самое на английском: The Customer transfers Executor monthly advance payment according to the present agreement and invoice, in which the actual amount is based on Executors report and the amount of hours the Executor spent developing the Software. Final payment according to Technical Specification is done by the Customer to the bank account o the Executor according to the Executor's invoices not later than after 15 (fifteen) calendar days from the date on signing Acceptance Act by the parties.

Встал вопрос - как обменяться подписанными договорами с заказчиком. Ответ нашелся в другой статье с хабра - Как организовать работу с заказчиками из других городов?. Сделали по предложенной методике (копирую из оригинала почти дословно):
  • В нижний колонтитул договора вставляем подписи обеих сторон. Распечатываем и подписываем каждую страницу договора, на последнюю ставим свою печать.
  • Отправляем скан договора по емейлу заказчику.
  • Заказчик подписывает копию на каждой странице, на последней ставит свою печать и отправляем обратно вам.
  • Вы распечатываете полученный документ и на каждой странице в произвольном месте ставите свою печать, подпись и пишите «Копия верна»
Процедуру можно еще упростить, получив сканы подписи клиента и отсканировав свою подпись. В нижние колонтитулы вставляются обе подписи, договор распечатывается, далее на каждой странице пишется "копия верна" и ставится подпись. Все. Банк такая копия договора устроила.

В реквизитах договора указывается номер транзитного счета. Крайне важно, чтобы наименование клиента (контрагента) в договоре было в точности таким, как он зарегистрирован в своем банке и чтобы его наименование в платежных документах совпадало с его наименованием в договоре.

Про паспорт сделки, оформление счета и нюансы получения оплаты напишу в следующий раз.

Update: см. Расчетный счет ИП. Паспорт сделки и процесс получения денег от зарубежного заказчика.

Полезны статьи на хабре
Опыт регистрации ИП для ведения бизнеса связанного с ИТ. Как всегда, много полезного в комментариях.

Тонкости при работе с иностранным заказчиком

Почему ИТшнику стоит стать ИПшником и почему не стоит регистрировать ООО

Update 2012Для удобства выложил образец договора с иностранным заказчиком, образец акта выполненных работ и образцы доп. соглашений - о продлении и досрочном завершении договора. Взять можно здесь.

вторник, 7 сентября 2010 г.

svchost.exe грузит CPU на 100% при запуске Windows 7

Приятель обратился с проблемой - при запуске Windows 7 процессор в течении 5-10 минут загружен на 100%. Системе около года. Раньше все было нормально, а последние 2-3 месяца начались проблемы. Понятно, что что-то установил (или что-то авто-установилось) - но что именно?

Поискал в интернете - сообщений на эту тему масса, но четкого ответа - почему так происходит - нет. Одним помогает обновление видеодрайвера, другим - чистка куллера, третьим - замена USB портов, четвертым - выключение брандмауэра, отключение протокола IP6, чистка host-файла. Многим помогает установка/отмена обновлений Windows. Но какое именно обновление нужно откатить в нашем случае я так и не разобрался.

В safe mode проблема не воспроизвелась, так что вариант железячных проблем мы отмели. Обновление драйверов на видеокарте не помогло. Host файл был чист. Отключение брандмауэра роли не сыграло. С помощью Autoruns почистил автозагрузку от всякого барахла - загрузка компьютера в целом слегка ускорилась, но на время запуска svchost, естественно, это не повлияло. Process Explorer показал, что в рамках проблемных процессов svchost сидят, в основном, различные сетевые службы (но не только).

Сделал следующее: стал отключать службы пачками, перезагружать компьютер и смотреть, исчезла ли проблема. В какой-то момент загрузка снизилась до 80 секунд. Для данного (далеко не нового) компьютера - это нормально. Стал включать одну за одной отключенные службы и нашел двух виновников длительной загрузки:
  • Вспомогательная служба IP
  • Модули ключей IPsec для обмена ключами в Интернете и протокола IP с проверкой
    подлинности
Если их включить, время загрузки увеличивалось сразу с 80 до 300 секунд. Пришлось выключить на время эти службы. Будем ждать, пока их подлатают.

Update: Вот здесь даны инструкции по настройке служб под Windows 7 - какие службы и когда можно отключить.

Update2: Хорошая статья на Хабре, где объясняется что такое IP6 и IPsec.