В «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);// Дамп всех документов
?>
Применять данный «парсер» не рекомендуется на каких-то крупных проектах, так как класс не учитывает многих нюансов формата обмена.
Также нет никакой обработки ошибок. Данный класс создан только для ознакомительных целей и не претендует на гениальность, но с моей точки зрения как отправная точка вполне себе годен.
Спасибо за внимание и заранее спасибо за комментарии.