Определение взаимозависимых лиц согласно ст. 105.1 Налогового кодекса РФ достаточно тривиальная задача для корпоративного юриста.
Обычно это не вызывает сложностей и, кажется, зачем здесь что-то автоматизировать?
Все верно, если общество два или три сравнить их составы СД нет никаких проблем. Но, если обществ больше двух десятков и при этом в разных обществах разные составы директоров в том числе по количеству членов? Здесь уже надо потратить время. Потратим его на программу, которая за нас вычислит взаимосвязанные стороны, анализируя составы советов директоров.
Напомним, что взаимозависимые лица определяются по ряду критериев, приведенных в НК РФ.
В пункте 2 ст. 105.1 НК РФ перечислены основания, согласно которым лица признаются взаимозависимыми. Итак, для целей налогообложения взаимозависимыми лицами являются:
Оснований много, но нам интересно одно из них, а именно:
— организации, в которых более 50% совета директоров составляют одни и те же физические лица.
Данное основание отличается от остальных тем, что юристу необходимо сравнить все составы советов директоров в обществах на совпадение их членов более 50%.
Допустим все составы СД у нас сведены в таблицу Excel с советами директоров и общим количеством обществ более двадцати:
Нам необходимо, чтобы наша программа, пройдя по таблице, отбирала общества если там будет совпадение более чем 50 % от общего числа членов совета директоров. Далее программа должна выводить результат либо на экран, либо в файл.
Логически программа будет выполнять следующий алгоритм. Получив от пользователя ФИО директоров, она будет сравнивать их с каждой строкой Excel, где содержатся ФИО директоров по каждому обществу. То есть каждые три члена СД пользователя из 5-ти сравниваются с каждыми 3-мя из 5-ти в таблице. На данном этапе программа не будет анализировать СД с числом членов более 5, пропуская их.
Первые строки нашей программы будут стандартными:
Здесь мы импортировали модуль для работы с Excel и открыли файл с нашей таблицей.
Теперь мы предложим пользователю ввести пять членов СД, которых программа далее будет искать в обществах для сравнения. Всех введенных пользователем членов СД запишем в переменные a,b,c,e,f:
Здесь важный момент. ФИО директора надо вводить без пробелов, например ИвановИ.И. В таком же виде ФИО директоров должны присутствовать в таблице Excel.
Создадим два списка. Один пустой, второй с обществами, где СД более чем с 5 членами:
Также мы открыли текстовый файл 55555.txt, в который будем сохранять результаты.Совпадение СД более, чем на 50 % означает, что 3 члена из 5-ти должны совпасть. Значит программа должна произвести 10 проверок на совпадение фамилий. Именно столько комбинаций может быть для СД из 5-ти членов.
Поэтому, чтобы не писать 10 раз один и тот же код, делая программу громоздкой, мы создадим функцию и далее вызовем (исполним ) ее 10 раз.
Вот наша функция:
Разберем код.
Мы задали границы таблицы, по которой пойдет программа B2:L36. Если ячейка пустая, она будет пропущена.
Далее в функция будет рассматривать ФИО 1-го директора, если ФИО в ячейке соответствует ФИО, введенного пользователем, то функция идет дальше и сравнивает 2-го, затем 3-го директора. В конце функция формирует список обществ и записывает каждое из них в файл 55555.txt.
После того, как функция написана она автоматически не будет исполнена программой.
Ее необходимо вызвать:
Но здесь мы вызвали функцию только для первой тройки директоров. Надо повторить вызов функции и для остальных комбинаций:
Запустим программу и введем в окне интерпретатора python любые 5-ть ФИО директоров из
тех, что хотя бы раз встречаются в таблице excel:
После того, как программа исполнится, заглянем в файл, который создаст программа —
55555.txt:
В файле – номера обществ, где были найдены совпадения. Надо обратить внимание, что это номера обществ из столбца А, а не номера строки Excel:
Программа готова, но необходимо помнить, что она не анализирует составы СД с членами более 5 человек!
Скачать код программы – здесь.
Скачать тестовую таблицу – здесь.
P.S.: любые совпадения в таблице с реальными личностями случайны.
Обычно это не вызывает сложностей и, кажется, зачем здесь что-то автоматизировать?
Все верно, если общество два или три сравнить их составы СД нет никаких проблем. Но, если обществ больше двух десятков и при этом в разных обществах разные составы директоров в том числе по количеству членов? Здесь уже надо потратить время. Потратим его на программу, которая за нас вычислит взаимосвязанные стороны, анализируя составы советов директоров.
Немного определений
Напомним, что взаимозависимые лица определяются по ряду критериев, приведенных в НК РФ.
В пункте 2 ст. 105.1 НК РФ перечислены основания, согласно которым лица признаются взаимозависимыми. Итак, для целей налогообложения взаимозависимыми лицами являются:
- организации, в случае если одна организация прямо и (или) косвенно участвует в другой организации и доля такого участия составляет более 25%;
- физическое лицо и организация в случае, если такое физическое лицо прямо и (или) косвенно участвует в такой организации и доля такого участия составляет более 25%;
- организации, в случае если одно и то же лицо прямо и (или) косвенно участвует в этих организациях и доля такого участия в каждой организации составляет более 25%;
- организация и лицо (в том числе физическое лицо совместно с его супругом (супругой), родителями (в том числе усыновителями), детьми (в том числе усыновленными), полнородными и неполнородными братьями и сестрами, опекунами (попечителями) и подопечными), имеющие полномочия по назначению (избранию) единоличного исполнительного органа этой организации или по назначению (избранию) не менее 50% состава коллегиального исполнительного органа или совета директоров (наблюдательного совета) этой организации;
- организации, единоличные исполнительные органы которых либо не менее 50% состава коллегиального исполнительного органа или совета директоров (наблюдательного совета) которых назначены или избраны по решению одного и того же лица (физического лица совместно с его супругом (супругой), родителями (в том числе усыновителями), детьми (в том числе усыновленными), полнородными и неполнородными братьями и сестрами, опекунами (попечителями) и подопечными);
- организации, в которых более 50% состава коллегиального исполнительного органа или совета директоров (наблюдательного совета) составляют одни и те же физические лица совместно с их супругом (супругой), родителями (в том числе усыновителями), детьми (в том числе усыновленными), полнородными и неполнородными братьями и сестрами, опекунами (попечителями) и подопечными;
- организация и лицо, осуществляющее полномочия ее единоличного исполнительного органа;
- организации, в которых полномочия единоличного исполнительного органа осуществляет одно и то же лицо;
- организации и (или) физические лица в случае, если доля прямого участия каждого предыдущего лица в каждой последующей организации составляет более 50%;
- физические лица в случае, если одно физическое лицо подчиняется другому физическому лицу по должностному положению;
- физическое лицо, его супруг (супруга), родители (в том числе усыновители), дети (в том числе усыновленные), полнородные и неполнородные братья и сестры, опекун (попечитель) и подопечный.
Ближе к делу
Оснований много, но нам интересно одно из них, а именно:
— организации, в которых более 50% совета директоров составляют одни и те же физические лица.
Данное основание отличается от остальных тем, что юристу необходимо сравнить все составы советов директоров в обществах на совпадение их членов более 50%.
Допустим все составы СД у нас сведены в таблицу Excel с советами директоров и общим количеством обществ более двадцати:
Нам необходимо, чтобы наша программа, пройдя по таблице, отбирала общества если там будет совпадение более чем 50 % от общего числа членов совета директоров. Далее программа должна выводить результат либо на экран, либо в файл.
Логически программа будет выполнять следующий алгоритм. Получив от пользователя ФИО директоров, она будет сравнивать их с каждой строкой Excel, где содержатся ФИО директоров по каждому обществу. То есть каждые три члена СД пользователя из 5-ти сравниваются с каждыми 3-мя из 5-ти в таблице. На данном этапе программа не будет анализировать СД с числом членов более 5, пропуская их.
Первые строки нашей программы будут стандартными:
import openpyxl
wb = openpyxl.load_workbook('sd3.xlsx')
sheet=wb.get_active_sheet()
Здесь мы импортировали модуль для работы с Excel и открыли файл с нашей таблицей.
Теперь мы предложим пользователю ввести пять членов СД, которых программа далее будет искать в обществах для сравнения. Всех введенных пользователем членов СД запишем в переменные a,b,c,e,f:
a=str(input("Директор-1: "))
b=str(input("Директор-2: "))
c=str(input("Директор-3: "))
e=str(input("Директор-4: "))
f=str(input("Директор-5: "))
Здесь важный момент. ФИО директора надо вводить без пробелов, например ИвановИ.И. В таком же виде ФИО директоров должны присутствовать в таблице Excel.
Создадим два списка. Один пустой, второй с обществами, где СД более чем с 5 членами:
found = []
found2=[1,10,11,12,13,14,18,27,31,32] # общества в таблице sd3,где СД больше 5 чел.
h = open('55555.txt','a')
Также мы открыли текстовый файл 55555.txt, в который будем сохранять результаты.Совпадение СД более, чем на 50 % означает, что 3 члена из 5-ти должны совпасть. Значит программа должна произвести 10 проверок на совпадение фамилий. Именно столько комбинаций может быть для СД из 5-ти членов.
Поэтому, чтобы не писать 10 раз один и тот же код, делая программу громоздкой, мы создадим функцию и далее вызовем (исполним ) ее 10 раз.
Заряжаем функцию
Вот наша функция:
def myfun(x,y,z):
for rowOfCellObjects in sheet['B2':'L36']:
for cellObj in rowOfCellObjects:
if cellObj.value ==None:
continue
#print (cellObj)
if cellObj.value == x:
for cellObj in rowOfCellObjects:
if cellObj.value == y:
for cellObj in rowOfCellObjects:
if cellObj.value == z:
d = list(cellObj.coordinate)
d[0]='A'
dd=d[0]+d[1]
if len(d)>2:
dd=d[0]+d[1]+d[2]
i=sheet[str(dd)].value #значение из столбца А,где найдены совпадения 3-х директоров
q = cellObj.row
if i not in found and i not in found2:
found.append(i)
h.write (str(i)+'\n')
Разберем код.
Мы задали границы таблицы, по которой пойдет программа B2:L36. Если ячейка пустая, она будет пропущена.
Далее в функция будет рассматривать ФИО 1-го директора, если ФИО в ячейке соответствует ФИО, введенного пользователем, то функция идет дальше и сравнивает 2-го, затем 3-го директора. В конце функция формирует список обществ и записывает каждое из них в файл 55555.txt.
После того, как функция написана она автоматически не будет исполнена программой.
Ее необходимо вызвать:
myfun(a,b,c)
Но здесь мы вызвали функцию только для первой тройки директоров. Надо повторить вызов функции и для остальных комбинаций:
myfun(a,b,e)
myfun(a,b,f)
myfun(a,e,f)
myfun(a,c,e)
myfun(a,c,f)
myfun(b,c,e)
myfun(b,c,f)
myfun(b,e,f)
myfun(c,e,f)
h.close()
Запускаем
Запустим программу и введем в окне интерпретатора python любые 5-ть ФИО директоров из
тех, что хотя бы раз встречаются в таблице excel:
После того, как программа исполнится, заглянем в файл, который создаст программа —
55555.txt:
В файле – номера обществ, где были найдены совпадения. Надо обратить внимание, что это номера обществ из столбца А, а не номера строки Excel:
Программа готова, но необходимо помнить, что она не анализирует составы СД с членами более 5 человек!
Скачать код программы – здесь.
Скачать тестовую таблицу – здесь.
P.S.: любые совпадения в таблице с реальными личностями случайны.
Комментарии (10)
Satim
06.08.2019 10:27как то так
def myfun(x, y, z): # получим множество кортежей с директорами directors = set(tuple(x.value for x in sheet['C2':'L36'].rows)) # Получим список всех идентификаторов организаций companies = tuple(x.value for x in sheet['А2':'A36']) data_dict = dict(zip(companies, directors)) checked_directors = set(x, y, z) for key, value in data_dict: if checked_directors.issubset(value): h.write(str(key) + '\n')
zoldaten Автор
06.08.2019 12:38Пока ошибка:
directors = set(tuple(x.value for x in sheet['B2':'L36'].rows))
AttributeError: 'tuple' object has no attribute 'rows'
BasicWolf
Я правильно понимаю что эта задача сводится к
Дано n множеств N1, N2,… Nn: ?1 ? k ? n |Nk| ? 1
Найти множества: |Nk ? Nj| ? max(|Nk|, |Nj|) / 2: j ? k
?
Потому что в этом случае решение укладывается в 3 строки:
zoldaten Автор
Общий смысл задачи: проверить, что любые 3 директора из 5 предложенных пользователем должны находиться в строке с директорами общества.
BasicWolf
Спасибо! Но ведь тогда всё ещё проще:
A в предыдущем примере так и вообще ничего вводить не надо — программа сама найдёт все организации в которых пересечение директоров больше 50%. И уже в этом результате имеет смысл искать конкретные имена.
zoldaten Автор
По 1-му коду:
да, он выявил, что есть пересечение по 1,2,3, но в каких обществах не указал.
Кроме того, пользователь вводит 5-ть человек, а не троих. Из этих 5-х надо понять кто трое есть в строке с обществом в любой комбинации.
По 2-му коду.
Вывод:
{1, 2, 3, 4}
{1, 2, 3, 5}
{3, 4, 5, 6, 7}
Но в третьей строке нет пересечения! Там нет троицы «1,2,3».
BasicWolf
Поторопился:
По 1-му коду — ну да, это лишь "заготовка" демонстрирующая основную идею. К ней можно приделать и красивый вывод и вообще всё что угодно :)
zoldaten Автор
В таком случае рискну предположить, что сам python всего лишь заготовка, демонстрирующая основную идею )