Добавлен модуль чтения выписки в формате 1с txt
Этот коммит содержится в:
родитель
0b8d6e42d4
коммит
a2d7a7913f
8 изменённых файлов: 283 добавлений и 1 удалений
2
go.mod
2
go.mod
|
@ -18,7 +18,7 @@ require (
|
|||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/yosuke-furukawa/json5 v0.1.1 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
|
|
2
go.sum
2
go.sum
|
@ -56,6 +56,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
|
39
pkg/delo_lib/delo_lib.go
Обычный файл
39
pkg/delo_lib/delo_lib.go
Обычный файл
|
@ -0,0 +1,39 @@
|
|||
package delo_lib
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ДатувКвартал(in string) (int, error) {
|
||||
parts := strings.Split(in, ".")
|
||||
if len(parts) < 3 {
|
||||
return 0, errors.New("формат даты")
|
||||
}
|
||||
месяц, err := strconv.ParseInt(parts[1], 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
квартал, err := МесяцвКвартал(месяц)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return квартал, nil
|
||||
}
|
||||
|
||||
func МесяцвКвартал(in int64) (int, error) {
|
||||
if in < 1 || in > 12 {
|
||||
return 0, errors.New("неправильный месяц")
|
||||
}
|
||||
|
||||
switch in {
|
||||
case 1, 2, 3:
|
||||
return 1, nil
|
||||
case 4, 5, 6:
|
||||
return 2, nil
|
||||
case 7, 8, 9:
|
||||
return 3, nil
|
||||
}
|
||||
return 4, nil
|
||||
}
|
3
pkg/input/txt/features/app.feature
Обычный файл
3
pkg/input/txt/features/app.feature
Обычный файл
|
@ -0,0 +1,3 @@
|
|||
# Во имя Бога Милостивого, Милосердного!!!
|
||||
# language: ru
|
||||
Функциональность: Конфиг Txt
|
51
pkg/input/txt/init_test.go
Обычный файл
51
pkg/input/txt/init_test.go
Обычный файл
|
@ -0,0 +1,51 @@
|
|||
package txt
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
. "my/schet/pkg/testlib"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/godog/colors"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
|
||||
// -----------------------
|
||||
ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
|
||||
beforeScenario()
|
||||
return ctx, nil
|
||||
})
|
||||
ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) {
|
||||
afterScenario()
|
||||
return ctx, nil
|
||||
})
|
||||
InitializeGomegaForGodog(ctx)
|
||||
_ = Ω
|
||||
}
|
||||
|
||||
func InitializeSuite(tsc *godog.TestSuiteContext) {
|
||||
tsc.BeforeSuite(beforeSuite)
|
||||
tsc.AfterSuite(afterSuite)
|
||||
}
|
||||
|
||||
func TestMain(t *testing.T) {
|
||||
var opts = godog.Options{
|
||||
Output: colors.Colored(os.Stdout),
|
||||
Strict: true,
|
||||
StopOnFailure: true,
|
||||
TestingT: t,
|
||||
}
|
||||
|
||||
godog.BindCommandLineFlags("godog.", &opts)
|
||||
godog.TestSuite{
|
||||
Name: "app",
|
||||
TestSuiteInitializer: InitializeSuite,
|
||||
ScenarioInitializer: InitializeScenario,
|
||||
Options: &opts,
|
||||
}.Run()
|
||||
}
|
48
pkg/input/txt/stroka.go
Обычный файл
48
pkg/input/txt/stroka.go
Обычный файл
|
@ -0,0 +1,48 @@
|
|||
package txt
|
||||
|
||||
import (
|
||||
"my/schet/pkg/delo_lib"
|
||||
"my/schet/pkg/input/config"
|
||||
"my/schet/pkg/schet"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type СтрокаДокумента struct {
|
||||
год *schet.Год
|
||||
parts []string
|
||||
дляДохода *config.Доход
|
||||
}
|
||||
|
||||
func NewСтрокаДокумента(год *schet.Год, parts []string, дляДохода *config.Доход) *СтрокаДокумента {
|
||||
c := &СтрокаДокумента{
|
||||
год: год,
|
||||
parts: parts,
|
||||
дляДохода: дляДохода,
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *СтрокаДокумента) Заполнить() error {
|
||||
switch c.parts[0] {
|
||||
case "Сумма":
|
||||
сумма, err := strconv.ParseFloat(c.parts[1], 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.дляДохода.Сумма = сумма
|
||||
case "Дата":
|
||||
квартал, err := delo_lib.ДатувКвартал(c.parts[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.дляДохода.Квартал = квартал
|
||||
case "ПолучательСчет":
|
||||
if c.parts[1] != c.год.Счёт() {
|
||||
return ErrНеподходящийДокумент
|
||||
}
|
||||
case "Плательщик1":
|
||||
c.дляДохода.Клиент = c.parts[1]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
108
pkg/input/txt/txt.go
Обычный файл
108
pkg/input/txt/txt.go
Обычный файл
|
@ -0,0 +1,108 @@
|
|||
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 == "КонецДокумента"
|
||||
}
|
31
pkg/input/txt/txt_test.go
Обычный файл
31
pkg/input/txt/txt_test.go
Обычный файл
|
@ -0,0 +1,31 @@
|
|||
package txt
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
type testData struct {
|
||||
}
|
||||
|
||||
var (
|
||||
t *testData
|
||||
)
|
||||
|
||||
func resetTestData() {
|
||||
t = &testData{}
|
||||
}
|
||||
|
||||
func beforeSuite() {
|
||||
}
|
||||
func afterSuite() {
|
||||
}
|
||||
|
||||
func beforeScenario() {
|
||||
resetTestData()
|
||||
_ = Ω
|
||||
|
||||
}
|
||||
func afterScenario() {
|
||||
}
|
||||
|
||||
// -----------------------
|
Загрузка…
Создание таблицы
Сослаться в новой задаче