В «1С Бухгалтерия» предусмотрен фомат обмена текстовой информацией с Банковскими системами. Именно в таком формате Банки предоставляют выписки по счетам Организаций.
Не так давно на одном из проектов возникла потребность «парсить» такие выписки и обрабатывать их. Тогда после поисков в интернете я обнаружил что: или я плохо ищу или люди не хотят делиться готовыми решениями.
Зайдя на сайт 1С я увидел, что формат вполне себе простой и понятный даже программисту без особого опыта.
Файл выписки представляет из себя простой текстовый документ.
Значит если документ текстовый то и «парсить» его легко. Данные в файле представлены в формате:
Следовательно достаточно принять файл за массив строк и начинать проходить по этому массиву циклом. Для удобства парсер возвращает массив объектов.
Применять данный «парсер» не рекомендуется на каких-то крупных проектах, так как класс не учитывает многих нюансов формата обмена.
Также нет никакой обработки ошибок. Данный класс создан только для ознакомительных целей и не претендует на гениальность, но с моей точки зрения как отправная точка вполне себе годен.
Спасибо за внимание и заранее спасибо за комментарии.
Не так давно на одном из проектов возникла потребность «парсить» такие выписки и обрабатывать их. Тогда после поисков в интернете я обнаружил что: или я плохо ищу или люди не хотят делиться готовыми решениями.
Зайдя на сайт 1С я увидел, что формат вполне себе простой и понятный даже программисту без особого опыта.
Файл выписки представляет из себя простой текстовый документ.
Пример файла
1CClientBankExchange ВерсияФормата=1.02 Кодировка=Windows Отправитель=Cистема Солнышко Интернет-Банк Получатель=Бухгалтерский учет, редакция 4.4 ДатаНачала=27.11.2013 ДатаКонца=27.11.2014 РасчСчет=12345678901234567890 СекцияРасчСчет ДатаНачала=27.11.2013 ДатаКонца=27.11.2014 РасчСчет=12345678901234567890 НачальныйОстаток=0 ВсегоПоступило=68770 ВсегоСписано=68770 КонечныйОстаток=0 КонецРасчСчет СекцияДокумент=Банковский ордер Номер=1 Дата=26.12.2013 Сумма=1000 ДатаСписано=26.12.2013 ДатаПоступило= ПлательщикСчет=12345678901234567890 Плательщик=ИНН 778899001122 Иванов Иван Иванович (ИП) ПлательщикИНН= 778899001122 Плательщик1=Иванов Иван Иванович (ИП) ПлательщикРасчСчет=12345678901234567890 ПлательщикБанк1=ОАО АКБ "Солнышко" ПлательщикБанк2=г. МОСКВА ПлательщикБИК=044525201 ПлательщикКорсчет=98765432198765432100 ПлательщикКорсчет=98765432198765432100 ПолучательСчет=89765456787654345678 Получатель=ИНН 7765434566\775001001 ОАО АКБ "Солнышко" ПолучательИНН=7765434566 Получатель1=ОАО АКБ "Солнышко" ПолучательРасчСчет=89765456787654345678 ПолучательБанк1=ОАО АКБ "Солнышко" ПолучательБанк2=г. МОСКВА ПолучательБИК=044525201 ПолучательКорсчет=98765432198765432100 ВидОплаты=17 НазначениеПлатежа=Комиссия за открытие счета согласно тарифам ОАО АКБ "Солнышко" КонецДокумента СекцияДокумент=Платежное поручение Номер=176 Дата=26.12.2013 Сумма=4770 ДатаСписано= Плательщик=ИНН 7725747515\772501001 ООО "ВИОСН" ПлательщикИНН=7725747515 ПлательщикСчет=40702810822000034869 Плательщик1=ООО "ВИОСН" ПлательщикРасчСчет=40702810822000034869 ПлательщикБанк1=АКБ "АБСОЛЮТ БАНК" (ОАО) ПлательщикБанк2=г. МОСКВА ПлательщикБИК=044525976 ПлательщикКорсчет=30101810500000000976 ДатаПоступило=26.12.2013 Получатель=ИНН 778899001122 ИП Иванов Иван Иванович ПолучательИНН=778899001122 ПолучательСчет=12345678901234567890 Получатель1=ИП Иванов Иван Иванович ПолучательРасчСчет=12345678901234567890 ПолучательБанк1=ОАО АКБ "Солнышко" ПолучательБанк2=г. МОСКВА ПолучательБИК=044525201 ПолучательКорсчет=98765432198765432100 ВидОплаты=01 СрокПлатежа=26.12.2013 Очередность=5 НазначениеПлатежа=Оплата по счету №1 от 26 декабря (за услуги по обслуживанию сайта ) НДС не облагается. КонецДокумента СекцияДокумент=Банковский ордер Номер=1 Дата=10.01.2014 Сумма=20 ДатаСписано=10.01.2014 ДатаПоступило= ПлательщикСчет=12345678901234567890 Плательщик=ИНН 778899001122 Иванов Иван Иванович (ИП) ПлательщикИНН=778899001122 Плательщик1=Иванов Иван Иванович (ИП) ПлательщикРасчСчет=12345678901234567890 ПлательщикБанк1=ОАО АКБ "Солнышко" ПлательщикБанк2=г. МОСКВА ПлательщикБИК=044525201 ПлательщикКорсчет=98765432198765432100 ПолучательСчет=70601810200021210220 Получатель=ИНН 7765434566\775001001 ОАО АКБ "Солнышко" ПолучательИНН=7765434566 Получатель1=ОАО АКБ "Солнышко" ПолучательРасчСчет=70601810200021210220 ПолучательБанк1=ОАО АКБ "Солнышко" ПолучательБанк2=г. МОСКВА ПолучательБИК=044525201 ПолучательКорсчет=98765432198765432100 ВидОплаты=17 НазначениеПлатежа=Плата за прием и обработку платежных документов КонецДокумента СекцияДокумент=Платежное поручение Номер=1 Дата=10.01.2014 Сумма=3500 ДатаСписано=10.01.2014 Плательщик=ИНН 778899001122\772801001 Иванов Иван Иванович (ИП) ПлательщикИНН=778899001122 ПлательщикСчет=12345678901234567890 Плательщик1=Иванов Иван Иванович (ИП) ПлательщикРасчСчет=12345678901234567890 ПлательщикБанк1=ОАО АКБ "Солнышко" ПлательщикБанк2=г. МОСКВА ПлательщикБИК=044525201 ПлательщикКорсчет=98765432198765432100 ДатаПоступило= Получатель=ИНН 7707704692\772801001 ОАО "Единая электронная торговая площадка" ПолучательИНН=7707704692 ПолучательСчет=40702810000760001497 Получатель1=ОАО "Единая электронная торговая площадка" ПолучательРасчСчет=40702810000760001497 ПолучательБанк1=ОАО "БАНК МОСКВЫ" ПолучательБанк2=г. МОСКВА ПолучательБИК=044525219 ПолучательКорсчет=30101810500000000219 ВидОплаты=01 СтатусСоставителя=01 ПлательщикКПП=772801001 ПолучательКПП=772801001 ПоказательКБК=00000000000000000000 ОКАТО=0 ПоказательОснования=0 ПоказательПериода=0 ПоказательНомера=0 ПоказательДаты=10.01.2014 ПоказательТипа=0 СрокПлатежа=10.01.2014 Очередность=5 НазначениеПлатежа=Сумма 3500.00, в т.ч. НДС - 388,99 КонецДокумента КонецФайла
Значит если документ текстовый то и «парсить» его легко. Данные в файле представлены в формате:
Секция Ключ=Значение КонецСекции
Следовательно достаточно принять файл за массив строк и начинать проходить по этому массиву циклом. Для удобства парсер возвращает массив объектов.
Document.php - Модель документа с правилами назначения
<?php namespace bank; class Document { public $doctype; public $inbankid; public $docdate; public $summ; public $outdate; public $indate; public $payeraccount; public $payerinfo; public $payerinn; public $payer; public $payerdealaccount; public $payerbank1; public $payerbank2; public $payerbik; public $payerfixaccount; public $recieveraccount; public $recieverinfo; public $recieverinn; public $reciever1; public $recieverdealaccount; public $recieverbank1; public $recieverbank2; public $recieverbik; public $recieverfixaccount; public $paytype; public $paydirection; public $makerstatus; public $payerkpp; public $recieverkpp; public $showerkbk; public $okato; public $showerfundament; public $showerperiod; public $showernumber; public $showerdate; public $showertype; public $paymentperiod; public $quenue; public function __construct() { } public function rules($rule) { $rules = [ 'СекцияДокумент' => 'doctype', 'Номер' => 'inbankid', 'Дата' => 'docdate', 'Сумма' => 'summ', 'ДатаСписано' => 'outdate', 'ДатаПоступило' => 'indate', 'ПлательщикСчет' => 'payeraccount', 'Плательщик' => 'payerinfo', 'ПлательщикИНН' => 'payerinn', 'Плательщик1' => 'payer', 'ПлательщикРасчСчет' => 'payerdealaccount', 'ПлательщикБанк1' => 'payerbank1', 'ПлательщикБанк2' => 'payerbank2', 'ПлательщикБИК' => 'payerbik', 'ПлательщикКорсчет' => 'payerfixaccount', 'ПолучательСчет' => 'recieveraccount', 'Получатель' => 'recieverinfo', 'ПолучательИНН' => 'recieverinn', 'Получатель1' => 'reciever1', 'ПолучательРасчСчет' => 'recieverdealaccount', 'ПолучательБанк1' => 'recieverbank1', 'ПолучательБанк2' => 'recieverbank2', 'ПолучательБИК' => 'recieverbik', 'ПолучательКорсчет' => 'recieverfixaccount', 'ВидОплаты' => 'paytype', 'НазначениеПлатежа' => 'paydirection', 'СтатусСоставителя' => 'makerstatus', 'ПлательщикКПП' => 'payerkpp', 'ПолучательКПП' => 'recieverkpp', 'ПоказательКБК' => 'showerkbk', 'ОКАТО' => 'okato', 'ПоказательОснования' => 'showerfundament', 'ПоказательПериода' => 'showerperiod', 'ПоказательНомера' => 'showernumber', 'ПоказательДаты' => 'showerdate', 'ПоказательТипа' => 'showertype', 'СрокПлатежа' => 'paymentperiod', 'Очередность' => 'quenue', ]; return $rules[$rule]; } public function set($section, $param) { $rulled = $this->rules($section); $this->$rulled = $param; } } ?>
Bank.php - Класс парсера документов
<?php include 'Document.php'; //Подключаем файл модели class Bank { protected $documents; // Свойство для хранения "отпарсенных" документов //Конструктор принимает на вход путь к файлу function __construct($fileaddr) { $maas = file($fileaddr); // Открываем файл как массив строк $documents = []; // Создаем пустой массив для хранения документов $docid = 0; // Устанавливаем счетчик ID документа на 0 foreach ($maas as $key => $value) { //Начинаем парсить каждую строку $value2 = rtrim($value); // Тримируем правую сторону строки от управляющих символов $value2 = mb_convert_encoding($value2, "utf-8", "windows-1251"); // Конвертируем значение в utf-8 так как изначальная кодировка файла windows-1251 $result = explode('=', $value2); // Разбиваем строку на Ключ => Значение if (count($result) == 2) { // Проверяем прошла ли разбивка if ($result[0] == 'СекцияДокумент') { //Если разбивка прошла и ключ результата СекцияДокумент то $workflow = new Document(); //Создаем новый Объект } if (isset($workflow)) { //Если объект создан то $workflow->set($result[0], $result[1]); // Назначаем Свойство, Содержимое } } else { //Если разбивка не прошла if ($result[0] == 'КонецДокумента') { //То проверяем конец ли это документа $documents[$docid] = $workflow; //Добавляем в массив документов новый документ $docid++; //Плюсуем счетчик } } } $this->documents = $documents; // Передаем массив документов в Свойство класса } function getDocs() { return $this->documents; // Отдаем документы по запросу } } ?>
Код для проверки
<?php include 'Bank.php'; //Подключаем парсер $file = 'export_to_1c.txt'; // Назначаем файл выписки $bank = new Bank($file); // Запускаем парсинг $docs = $bank->getDocs(); //Получаем все спарсенные документы var_dump($docs);// Дамп всех документов ?>
Применять данный «парсер» не рекомендуется на каких-то крупных проектах, так как класс не учитывает многих нюансов формата обмена.
Также нет никакой обработки ошибок. Данный класс создан только для ознакомительных целей и не претендует на гениальность, но с моей точки зрения как отправная точка вполне себе годен.
Спасибо за внимание и заранее спасибо за комментарии.
