From a2d7a7913fd27964b2277cf678eaedcdeee5f746 Mon Sep 17 00:00:00 2001 From: Softonik Date: Wed, 26 Jun 2024 16:54:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20=D1=87=D1=82?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2=D1=8B=D0=BF=D0=B8=D1=81=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=B2=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B5=20?= =?UTF-8?q?1=D1=81=20txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 2 +- go.sum | 2 + pkg/delo_lib/delo_lib.go | 39 +++++++++++ pkg/input/txt/features/app.feature | 3 + pkg/input/txt/init_test.go | 51 ++++++++++++++ pkg/input/txt/stroka.go | 48 +++++++++++++ pkg/input/txt/txt.go | 108 +++++++++++++++++++++++++++++ pkg/input/txt/txt_test.go | 31 +++++++++ 8 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 pkg/delo_lib/delo_lib.go create mode 100644 pkg/input/txt/features/app.feature create mode 100644 pkg/input/txt/init_test.go create mode 100644 pkg/input/txt/stroka.go create mode 100644 pkg/input/txt/txt.go create mode 100644 pkg/input/txt/txt_test.go diff --git a/go.mod b/go.mod index 79d3cac..1610e62 100644 --- a/go.mod +++ b/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 ) diff --git a/go.sum b/go.sum index 9b2e182..8e5e0cc 100644 --- a/go.sum +++ b/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= diff --git a/pkg/delo_lib/delo_lib.go b/pkg/delo_lib/delo_lib.go new file mode 100644 index 0000000..09b61ec --- /dev/null +++ b/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 +} diff --git a/pkg/input/txt/features/app.feature b/pkg/input/txt/features/app.feature new file mode 100644 index 0000000..3314c71 --- /dev/null +++ b/pkg/input/txt/features/app.feature @@ -0,0 +1,3 @@ +# Во имя Бога Милостивого, Милосердного!!! +# language: ru +Функциональность: Конфиг Txt diff --git a/pkg/input/txt/init_test.go b/pkg/input/txt/init_test.go new file mode 100644 index 0000000..be00131 --- /dev/null +++ b/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() +} diff --git a/pkg/input/txt/stroka.go b/pkg/input/txt/stroka.go new file mode 100644 index 0000000..58ea25d --- /dev/null +++ b/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 +} diff --git a/pkg/input/txt/txt.go b/pkg/input/txt/txt.go new file mode 100644 index 0000000..aa40fed --- /dev/null +++ b/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 == "КонецДокумента" +} diff --git a/pkg/input/txt/txt_test.go b/pkg/input/txt/txt_test.go new file mode 100644 index 0000000..59bb85d --- /dev/null +++ b/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() { +} + +// -----------------------