108 строки
2,5 КиБ
Go
108 строки
2,5 КиБ
Go
package txt
|
|
|
|
import (
|
|
"bufio"
|
|
"errors"
|
|
"io"
|
|
"my/schet/pkg/input/config"
|
|
"my/schet/pkg/schet"
|
|
"os"
|
|
"strings"
|
|
|
|
"golang.org/x/text/encoding/charmap"
|
|
"golang.org/x/text/transform"
|
|
)
|
|
|
|
var (
|
|
ErrНеподходящийДокумент = errors.New("неподходящий документ")
|
|
)
|
|
|
|
type TXT struct {
|
|
path string
|
|
config *config.Config
|
|
год *schet.Год
|
|
дляДохода *config.Доход
|
|
}
|
|
|
|
func NewTXT(path string) *TXT {
|
|
c := &TXT{
|
|
config: config.NewConfig(),
|
|
path: path,
|
|
}
|
|
return c
|
|
}
|
|
|
|
func (c *TXT) СчитатьиЗагрузитьвГод(год *schet.Год) error {
|
|
c.год = год
|
|
|
|
f, err := os.Open(c.path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
fenc := transform.NewReader(f, charmap.Windows1251.NewDecoder())
|
|
|
|
return c.парсить(fenc)
|
|
}
|
|
|
|
func (c *TXT) парсить(f io.Reader) error {
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
err := c.обработатьСтрокуФайла(line)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return scanner.Err()
|
|
}
|
|
|
|
func (c *TXT) обработатьСтрокуФайла(l string) error {
|
|
parts := strings.Split(l, "=")
|
|
if len(parts) < 2 {
|
|
return c.отправитьмиУдалитьПеременнуюДляДохода(l)
|
|
}
|
|
return c.создатьиЗаполнитьСтруктуруДляДохода(parts)
|
|
}
|
|
|
|
func (c *TXT) отправитьмиУдалитьПеременнуюДляДохода(l string) error {
|
|
if !конецДокумента(l) {
|
|
return nil
|
|
}
|
|
if c.дляДохода == nil {
|
|
return nil
|
|
}
|
|
|
|
err := c.год.ДобавитьДоход(c.дляДохода.Сумма, c.дляДохода.Квартал)
|
|
c.дляДохода = nil
|
|
|
|
return err
|
|
}
|
|
|
|
func (c *TXT) создатьиЗаполнитьСтруктуруДляДохода(parts []string) error {
|
|
if началоДокумента(parts) {
|
|
c.дляДохода = &config.Доход{}
|
|
return nil
|
|
}
|
|
|
|
if c.дляДохода == nil {
|
|
return nil
|
|
}
|
|
|
|
sd := NewСтрокаДокумента(c.год, parts, c.дляДохода)
|
|
err := sd.Заполнить()
|
|
if errors.Is(err, ErrНеподходящийДокумент) {
|
|
c.дляДохода = nil
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
func началоДокумента(parts []string) bool {
|
|
return parts[0] == "СекцияДокумент" && parts[1] == "Платежное поручение"
|
|
}
|
|
func конецДокумента(l string) bool {
|
|
return l == "КонецДокумента"
|
|
}
|