alpha version

This commit is contained in:
2025-02-03 17:49:29 -05:00
commit dac9e95d12
144 changed files with 5694 additions and 0 deletions

29
models/blacklist.go Normal file
View File

@ -0,0 +1,29 @@
package models
import (
"context"
"github.com/uptrace/bun"
)
type BlackList struct {
bun.BaseModel `bun:"table:blacklist"`
UserID int64 `bun:",pk,autoincrement"`
Name string `bun:"name,type:text,unique" json:"name" yaml:"name"`
TelegramID int64 `bun:"telegram_id,type:int,unique" json:"telegram_id" yaml:"telegram_id"`
TelegramUsername string `bun:"telegram_username,type:text,unique" json:"telegram_username" yaml:"telegram_username"`
}
var _ bun.AfterCreateTableHook = (*BlackList)(nil)
func (*BlackList) AfterCreateTable(ctx context.Context, query *bun.CreateTableQuery) error {
_, err := query.DB().NewCreateIndex().Model((*BlackList)(nil)).Index("idx_bl_telegram_id").Column("telegram_id").Exec(ctx)
if err != nil {
return err
}
_, err = query.DB().NewCreateIndex().Model((*BlackList)(nil)).Index("idx_bl_telegram_username").Column("telegram_username").Exec(ctx)
if err != nil {
return err
}
return nil
}

92
models/commands.go Normal file
View File

@ -0,0 +1,92 @@
package models
import (
"fmt"
"log"
"reflect"
"regexp"
"strconv"
)
var BtnCmd = map[string]int64{
"user_add": 1,
"user_edit": 2,
"user_detete": 3,
"users_list": 4,
"group_add": 11,
"group_edit": 12,
"group_delete": 13,
"groups_list": 14,
"receipt_add": 21,
"receipt_edit": 22,
"receipt_delete": 23,
"receipts_list": 24,
"item_add": 31,
"item_edit": 32,
"item_delete": 33,
"items_list": 34,
"merchant": 96,
"category": 97,
"tax": 98,
"total": 99,
}
// var btnPage = map[string]int64{
// "prev": 1,
// "next": 2,
// }
// TelegramBotCommand .
type TelegramBotCommand struct {
Cmd int64 // Internal Command ( user_add | user_edit | user_delete )
ID int64 // Internal UserID
RefCmd int64 // Internal Reference Command
RefID int64 // Internal Reference ID
TelegramID int64 // Telegram UserID
Pagination int64 // Pagination
Extra string // Internal String filed to pass Telegram FileID
}
// Unmarshal .
func (t *TelegramBotCommand) Unmarshal(c string) error {
r := regexp.MustCompile(`^(?P<Cmd>.*)\|(?P<ID>.*)\|(?P<RefCmd>.*)\|(?P<RefID>.*)\|(?P<TelegramID>.*)\|(?P<Pagination>.*)\|(?P<Extra>.*)$`)
m := r.FindStringSubmatch(c)
res := make(map[string]string)
for i, name := range r.SubexpNames() {
if i != 0 && name != "" {
res[name] = m[i]
}
}
for k, val := range res {
v := reflect.ValueOf(&t).Elem()
f := reflect.Indirect(v).FieldByName(k)
if !f.IsValid() {
continue
}
if f.Type().Kind() == reflect.Int64 {
age, err := strconv.Atoi(val)
if err != nil {
continue
}
f.SetInt(int64(age))
} else {
f.SetString(val)
}
}
log.Printf("CALLBACK (UNMARSHAL) %d|%d|%d|%d|%d|%d|%s", t.Cmd, t.ID, t.RefCmd, t.RefID, t.TelegramID, t.Pagination, t.Extra)
return nil
}
// Marshal .
func (t *TelegramBotCommand) Marshal() string {
return fmt.Sprintf("%d|%d|%d|%d|%d|%d|%s", t.Cmd, t.ID, t.RefCmd, t.RefID, t.TelegramID, t.Pagination, t.Extra)
}
// String .
func String(t *TelegramBotCommand) string {
return t.Marshal()
}

50
models/credit_cards.go Normal file
View File

@ -0,0 +1,50 @@
package models
import (
"context"
"time"
"github.com/uptrace/bun"
)
type CreditCard struct {
bun.BaseModel `bun:"table:credit_cards"`
CreditCardID int64 `bun:",pk,autoincrement" json:"credit_card_id" yaml:"credit_card_id"`
UserID int64 `json:"user_id" yaml:"user_id"`
Title string `bun:"title,type:text" json:"title,omitempty" yaml:"title,omitempty"`
Bank string `bun:"bank,type:text" json:"bank,omitempty" yaml:"bank,omitempty"`
Type string `bun:"type,type:text" json:"type,omitempty" yaml:"type,omitempty"`
Digits string `bun:"digits,type:text,unique" json:"digits,omitempty" yaml:"digits,omitempty"`
Created time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"created" yaml:"created"`
Updated time.Time `json:"updated" yaml:"updated"`
}
type CreditCards []*CreditCard
var _ bun.AfterCreateTableHook = (*CreditCard)(nil)
func (*CreditCard) AfterCreateTable(ctx context.Context, query *bun.CreateTableQuery) error {
_, err := query.DB().NewCreateIndex().Model((*CreditCard)(nil)).Index("idx_credit_card_title").Column("title").Exec(ctx)
if err != nil {
return err
}
_, err = query.DB().NewCreateIndex().Model((*CreditCard)(nil)).Index("idx_credit_card_type").Column("type").Exec(ctx)
if err != nil {
return err
}
_, err = query.DB().NewCreateIndex().Model((*CreditCard)(nil)).Index("idx_credit_card_digits").Column("digits").Exec(ctx)
if err != nil {
return err
}
return nil
}
// Add .
func (cc *CreditCard) Add(db *bun.DB, ctx context.Context) error {
_, err := db.NewInsert().Model(cc).On("CONFLICT (digits) DO UPDATE").Set("updated = EXCLUDED.updated").Exec(ctx)
if err != nil {
return err
}
return nil
}

92
models/groups.go Normal file
View File

@ -0,0 +1,92 @@
package models
import (
"context"
"github.com/uptrace/bun"
)
type Group struct {
bun.BaseModel `bun:"table:groups"`
UserID int64
GroupID int64 `bun:",pk,autoincrement"`
Name string `bun:"name,type:text" json:"name" yaml:"name"`
TelegramChatID int64 `bun:"telegram_chat_id,type:bigint" json:"telegram_chat_id" yaml:"telegram_chat_id"`
Users Users `bun:"m2m:group_to_users,join:Group=User"`
}
type GroupToUser struct {
GroupID int64 `bun:",pk"`
Group *Group `bun:"rel:belongs-to,join:group_id=user_id"`
UserID int64 `bun:",pk"`
User *User `bun:"rel:belongs-to,join:user_id=group_id"`
}
func NewGroup(j []byte) (*Group, error) {
g := &Group{}
return g, nil
}
// Add .
func (g *Group) Add(db *bun.DB, ctx context.Context) error {
_, err := db.NewInsert().Model(g).Exec(ctx)
if err != nil {
return err
}
return nil
}
// Update .
func (g *Group) Update(db *bun.DB, ctx context.Context) error {
_, err := db.NewUpdate().Model(g).WherePK().Exec(ctx)
if err != nil {
return err
}
return nil
}
// Remove .
func (g *Group) Remove(db *bun.DB, ctx context.Context) error {
_, err := db.NewDelete().Model(g).WherePK().Exec(ctx)
if err != nil {
return err
}
return nil
}
// UserAdd .
func (g *Group) UserAdd(db *bun.DB, ctx context.Context, u int64) error {
_, err := db.NewInsert().Model(g).Exec(ctx)
if err != nil {
return err
}
return nil
}
// UserList .
func (g *Group) UserList(db *bun.DB, ctx context.Context) (Users, error) {
var users Users
_, err := db.NewSelect().Model(&users).ScanAndCount(ctx)
if err != nil {
return nil, err
}
return users, nil
}
// UserRemove .
func (g *Group) UserRemove(db *bun.DB, ctx context.Context, u int) error {
_, err := db.NewInsert().Model(g).Exec(ctx)
if err != nil {
return err
}
return nil
}
func GroupExists(db *bun.DB, ctx context.Context, tid int64) bool {
exists, err := db.NewSelect().Model((*Group)(nil)).Where("telegram_chat_id = ?", tid).Exists(ctx)
if err != nil {
panic(err)
}
return exists
}

79
models/items.go Normal file
View File

@ -0,0 +1,79 @@
package models
import (
"context"
"github.com/uptrace/bun"
)
type Item struct {
bun.BaseModel `bun:"table:items"`
ItemID int64 `bun:",pk,autoincrement" json:"item_id" yaml:"item_id"`
ReceiptID int64 `json:"receipt_id" yaml:"receipt_id"`
Title string `bun:"item,type:text" json:"item" yaml:"item"`
Quantity float64 `bun:"quantity" json:"quantity" yaml:"quantity"`
Price float64 `bun:"price" json:"price" yaml:"price"`
Category string `bun:"category" json:"category" yaml:"category"`
}
type Items []*Item
var _ bun.AfterCreateTableHook = (*Item)(nil)
func (*Item) AfterCreateTable(ctx context.Context, query *bun.CreateTableQuery) error {
_, err := query.DB().NewCreateIndex().Model((*Item)(nil)).Index("idx_items_item").Column("item").Exec(ctx)
if err != nil {
return err
}
_, err = query.DB().NewCreateIndex().Model((*Item)(nil)).Index("idx_items_category").Column("category").Exec(ctx)
if err != nil {
return err
}
return nil
}
// Add .
func (i *Item) Add(db *bun.DB, ctx context.Context) error {
_, err := db.NewInsert().Model(i).Exec(ctx)
if err != nil {
return err
}
return nil
}
// Update .
func (i *Item) Update(db *bun.DB, ctx context.Context) error {
_, err := db.NewUpdate().Model(i).WherePK().Exec(ctx)
if err != nil {
return err
}
return nil
}
// Add .
func (i *Items) Add(db *bun.DB, ctx context.Context) error {
_, err := db.NewInsert().Model(i).Exec(ctx)
if err != nil {
return err
}
return nil
}
// List .
func (i *Items) List(db *bun.DB, ctx context.Context, r int) (Items, error) {
var items Items
_, err := db.NewSelect().Model(&items).Where("receipt_id = ?", r).ScanAndCount(ctx)
if err != nil {
return nil, err
}
return items, nil
}
// Remove .
func (i *Items) Remove(db *bun.DB, ctx context.Context) error {
_, err := db.NewDelete().Model(i).WherePK().Exec(ctx)
if err != nil {
return err
}
return nil
}

47
models/merchants.go Normal file
View File

@ -0,0 +1,47 @@
package models
import (
"context"
"time"
"github.com/uptrace/bun"
)
type Merchant struct {
bun.BaseModel `bun:"table:merchants"`
MerchantID int64 `bun:",pk,autoincrement" json:"merchant_id" yaml:"merchant_id"`
Title string `bun:"title" json:"title" yaml:"title"`
Address string `bun:"address,type:text,unique" json:"address,omitempty" yaml:"address,omitempty"`
Phone string `bun:"phone,type:text,unique" json:"phone,omitempty" yaml:"phone,omitempty"`
Created time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"created" yaml:"created"`
Updated time.Time `json:"updated" yaml:"updated"`
}
var _ bun.AfterCreateTableHook = (*Merchant)(nil)
func (*Merchant) AfterCreateTable(ctx context.Context, query *bun.CreateTableQuery) error {
_, err := query.DB().NewCreateIndex().Model((*Merchant)(nil)).Index("idx_merchant_title").Column("title").Exec(ctx)
if err != nil {
return err
}
_, err = query.DB().NewCreateIndex().Model((*Merchant)(nil)).Index("idx_merchant_address").Column("address").Exec(ctx)
if err != nil {
return err
}
_, err = query.DB().NewCreateIndex().Model((*Merchant)(nil)).Index("idx_merchant_phone").Column("phone").Exec(ctx)
if err != nil {
return err
}
return nil
}
// Add .
func (m *Merchant) Add(db *bun.DB, ctx context.Context) error {
_, err := db.NewInsert().Model(m).On("CONFLICT (phone) DO UPDATE").Set("updated = EXCLUDED.updated").Exec(ctx)
// _, err := db.NewInsert().Model(m).Exec(ctx)
if err != nil {
return err
}
return nil
}

119
models/receipts.go Normal file
View File

@ -0,0 +1,119 @@
package models
import (
"context"
"encoding/json"
"strings"
"time"
"github.com/uptrace/bun"
)
type Receipt struct {
bun.BaseModel `bun:"table:receipts"`
ReceiptID int64 `bun:",pk,autoincrement" json:"receipt_id" yaml:"receipt_id"`
UserID int64 `json:"user_id" yaml:"user_id"`
GroupID int64 `json:"group_id" yaml:"group_id"`
MerchantID int64 `json:"merchant_id" yaml:"merchant_id"`
CreditCardID int64 `json:"credit_card_id" yaml:"credit_card_id"`
CreditCard *CreditCard `bun:"credit_card,rel:belongs-to,join:credit_card_id=credit_card_id" json:"credit_card,omitempty" yaml:"credit_card,omitempty"`
Merchant *Merchant `bun:"merchant,rel:belongs-to,join:merchant_id=merchant_id" json:"merchant" yaml:"merchant"`
URL string `bun:"url" json:"url" yaml:"url"`
Type string `bun:"type" json:"type" yaml:"type"`
Category string `bun:"category" json:"category" yaml:"category"`
Items Items `bun:"rel:has-many,join:receipt_id=item_id" json:"items" yaml:"items"`
Tax float64 `bun:"tax" json:"tax,omitempty" yaml:"tax,omitempty"`
CCFee float64 `bun:"cc_fee" json:"cc_fee,omitempty" yaml:"cc_fee,omitempty"`
Tips float64 `bun:"tips" json:"tips,omitempty" yaml:"tips,omitempty"`
Total float64 `bun:"total" json:"total" yaml:"total"`
PaidWith string `bun:"paid_with" json:"paid_with" yaml:"paid_with"`
PaidAt string `bun:"paid_at" json:"paid_at" yaml:"paid_at"`
Created time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"created" yaml:"created"`
Updated time.Time `json:"updated" yaml:"updated"`
}
type Receipts []*Receipt
var _ bun.AfterCreateTableHook = (*Receipt)(nil)
// AfterCreateTable .
func (*Receipt) AfterCreateTable(ctx context.Context, query *bun.CreateTableQuery) error {
_, err := query.DB().NewCreateIndex().Model((*Receipt)(nil)).Index("idx_receipts_category").Column("category").Exec(ctx)
if err != nil {
return err
}
return nil
}
// NewReceipt .
func NewReceipt(j []byte) (*Receipt, error) {
var r *Receipt
if err := json.Unmarshal([]byte(j), &r); err != nil {
panic(err)
}
return r, nil
}
// Add .
func (r *Receipt) Add(db *bun.DB, ctx context.Context) error {
err := r.Merchant.Add(db, ctx)
if err != nil {
return err
}
err = r.CreditCard.Add(db, ctx)
if err != nil {
return err
}
_, err = db.NewInsert().Model(r).Exec(ctx)
if err != nil {
return err
}
if len(r.Items) > 0 {
for _, item := range r.Items {
item.ReceiptID = r.ReceiptID
item.Title = strings.Title(strings.ToLower(item.Title))
}
err = r.Items.Add(db, ctx)
if err != nil {
return err
}
}
return nil
}
// Update .
func (r *Receipt) Update(db *bun.DB, ctx context.Context) error {
_, err := db.NewUpdate().Model(r).WherePK().Exec(ctx)
if err != nil {
return err
}
return nil
}
// Remove .
func (r *Receipt) Remove(db *bun.DB, ctx context.Context) error {
err := r.Items.Remove(db, ctx)
if err != nil {
return err
}
_, err = db.NewDelete().Where("receipt_id = ?", r.ReceiptID).Exec(ctx)
if err != nil {
return err
}
return nil
}
// Select .
func (r *Receipt) Select(db *bun.DB, ctx context.Context, id int64) error {
err := db.NewSelect().Model(r).Where("receipt_id = ?", id).Scan(ctx)
if err != nil {
return err
}
return nil
}

5
models/settings.go Normal file
View File

@ -0,0 +1,5 @@
package models
type Settings struct {
OpenRegistration bool `bun:"open_registration,type:boolean" json:"open_registration" yaml:"open_registration"`
}

83
models/users.go Normal file
View File

@ -0,0 +1,83 @@
package models
import (
"context"
"time"
"github.com/uptrace/bun"
)
type User struct {
bun.BaseModel `bun:"table:users"`
UserID int64 `bun:",pk,autoincrement" json:"user_id" yaml:"user_id"`
GroupID int64 `json:"-" yaml:"-"`
Name string `bun:"name,type:text,unique" json:"name" yaml:"name"`
Email string `bun:"email,type:text" json:"email,omitempty" yaml:"email,omitempty"`
TelegramID int64 `bun:"telegram_id,type:int,unique" json:"telegram_id" yaml:"telegram_id"`
TelegramUsername string `bun:"telegram_username,type:text,unique" json:"telegram_username" yaml:"telegram_username"`
Receipts Receipts `bun:"rel:has-many,join:user_id=receipt_id"`
CreditCards CreditCards `bun:"rel:has-many,join:user_id=credit_card_id"`
Created time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"created" yaml:"created"`
Updated time.Time `json:"updated" yaml:"updated"`
}
type Users []*User
var _ bun.AfterCreateTableHook = (*User)(nil)
func (*User) AfterCreateTable(ctx context.Context, query *bun.CreateTableQuery) error {
_, err := query.DB().NewCreateIndex().Model((*User)(nil)).Index("idx_users_name").Column("name").Exec(ctx)
if err != nil {
return err
}
_, err = query.DB().NewCreateIndex().Model((*User)(nil)).Index("idx_users_telegram_id").Column("telegram_id").Exec(ctx)
if err != nil {
return err
}
_, err = query.DB().NewCreateIndex().Model((*User)(nil)).Index("idx_users_telegram_username").Column("telegram_username").Exec(ctx)
if err != nil {
return err
}
return nil
}
func NewUser(j []byte) (*User, error) {
u := &User{}
// u := &User{Name: fmt.Sprintf("%s %s", c.Sender().FirstName, c.Sender().LastName), TelegramID: c.Sender().ID, TelegramUsername: c.Sender().Username}
return u, nil
}
func (u *User) Add(db *bun.DB, ctx context.Context) error {
_, err := db.NewInsert().Model(u).Exec(ctx)
if err != nil {
return err
}
return nil
}
func (u *User) Update(db *bun.DB, ctx context.Context) error {
_, err := db.NewUpdate().Model(u).WherePK().Exec(ctx)
if err != nil {
return err
}
return nil
}
func (u *User) Remove(db *bun.DB, ctx context.Context) error {
_, err := db.NewDelete().Model(u).WherePK().Exec(ctx)
if err != nil {
return err
}
return nil
}
func UserExists(db *bun.DB, ctx context.Context, tid int64) bool {
exists, err := db.NewSelect().Model((*User)(nil)).Where("telegram_id = ?", tid).Exists(ctx)
if err != nil {
panic(err)
}
return exists
}

29
models/whitelist.go Normal file
View File

@ -0,0 +1,29 @@
package models
import (
"context"
"github.com/uptrace/bun"
)
type WhiteList struct {
bun.BaseModel `bun:"table:whitelist"`
UserID int64 `bun:",pk,autoincrement"`
Name string `bun:"name,type:text,unique" json:"name" yaml:"name"`
TelegramID int64 `bun:"telegram_id,type:int,unique" json:"telegram_id" yaml:"telegram_id"`
TelegramUsername string `bun:"telegram_username,type:text,unique" json:"telegram_username" yaml:"telegram_username"`
}
var _ bun.AfterCreateTableHook = (*WhiteList)(nil)
func (*WhiteList) AfterCreateTable(ctx context.Context, query *bun.CreateTableQuery) error {
_, err := query.DB().NewCreateIndex().Model((*WhiteList)(nil)).Index("idx_wl_telegram_id").Column("telegram_id").Exec(ctx)
if err != nil {
return err
}
_, err = query.DB().NewCreateIndex().Model((*WhiteList)(nil)).Index("idx_wl_telegram_username").Column("telegram_username").Exec(ctx)
if err != nil {
return err
}
return nil
}