package vchasno import ( "context" "time" "gitea.jeezft.xyz/jeezft/go-vchasno-kassa/api" ) const ( PayTypeCash = api.PayTypeCash PayTypeCard = api.PayTypeCard ) const ( TaskOpenShift = api.TaskOpenShift TaskSell = api.TaskSell TaskZReport = api.TaskZReport ) type Client struct { api *api.Client cashier string source string defaults *DefaultParams } type Config struct { Token string Cashier string Source string Defaults *DefaultParams } type DefaultParams struct { ProductName string Comment string Taxgrp string PayType int DefaultTimeout time.Duration } func NewClient(config Config) *Client { if config.Cashier == "" { config.Cashier = "cashier" } if config.Source == "" { config.Source = "api" } defaults := config.Defaults if defaults == nil { defaults = &DefaultParams{ Taxgrp: "1", PayType: PayTypeCard, DefaultTimeout: 30 * time.Second, } } if defaults.Taxgrp == "" { defaults.Taxgrp = "1" } if defaults.DefaultTimeout == 0 { defaults.DefaultTimeout = 30 * time.Second } return &Client{ api: api.NewClient(config.Token), cashier: config.Cashier, source: config.Source, defaults: defaults, } } func (c *Client) SetDefaults(defaults DefaultParams) { c.defaults = &defaults } func (c *Client) GetDefaults() DefaultParams { return *c.defaults } func (c *Client) OpenShift(ctx context.Context) (*api.SellResponse, error) { return c.api.OpenShift(ctx, c.cashier) } func (c *Client) CloseShift(ctx context.Context) (*api.ZReportResponse, error) { return c.api.CloseShift(ctx, c.cashier) } type SellParams struct { Name string Cnt int Price float64 Disc float64 Taxgrp string Comment string PayType int CardParams *CardParams Userinfo *api.Userinfo } type CardParams struct { Cardmask string BankID string RrnCode string AuthCode string } func (c *Client) NewSellParams() *SellParamsBuilder { return &SellParamsBuilder{ client: c, params: SellParams{ Name: c.defaults.ProductName, Cnt: 1, Taxgrp: c.defaults.Taxgrp, Comment: c.defaults.Comment, PayType: c.defaults.PayType, }, } } type SellParamsBuilder struct { client *Client params SellParams } func (b *SellParamsBuilder) Name(name string) *SellParamsBuilder { b.params.Name = name return b } func (b *SellParamsBuilder) Cnt(cnt int) *SellParamsBuilder { b.params.Cnt = cnt return b } func (b *SellParamsBuilder) Price(price float64) *SellParamsBuilder { b.params.Price = price return b } func (b *SellParamsBuilder) Disc(disc float64) *SellParamsBuilder { b.params.Disc = disc return b } func (b *SellParamsBuilder) Taxgrp(taxgrp string) *SellParamsBuilder { b.params.Taxgrp = taxgrp return b } func (b *SellParamsBuilder) Comment(comment string) *SellParamsBuilder { b.params.Comment = comment return b } func (b *SellParamsBuilder) PayCash() *SellParamsBuilder { b.params.PayType = PayTypeCash b.params.CardParams = nil return b } func (b *SellParamsBuilder) PayCard(cardmask, bankID, rrnCode, authCode string) *SellParamsBuilder { b.params.PayType = PayTypeCard b.params.CardParams = &CardParams{ Cardmask: cardmask, BankID: bankID, RrnCode: rrnCode, AuthCode: authCode, } return b } func (b *SellParamsBuilder) Userinfo(email, phone string) *SellParamsBuilder { b.params.Userinfo = &api.Userinfo{ Email: email, Phone: phone, } return b } func (b *SellParamsBuilder) Build() SellParams { return b.params } func (b *SellParamsBuilder) Execute(ctx context.Context) (*api.SellResponse, error) { return b.client.Sell(ctx, b.params) } func (b *SellParamsBuilder) ExecuteWithTimeout(timeout time.Duration) (*api.SellResponse, error) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() return b.client.Sell(ctx, b.params) } func (b *SellParamsBuilder) ExecuteDefault() (*api.SellResponse, error) { return b.ExecuteWithTimeout(b.client.defaults.DefaultTimeout) } func (c *Client) Sell(ctx context.Context, params SellParams) (*api.SellResponse, error) { if params.Taxgrp == "" { params.Taxgrp = c.defaults.Taxgrp } if params.Name == "" { params.Name = c.defaults.ProductName } if params.Comment == "" { params.Comment = c.defaults.Comment } if params.Cnt == 0 { params.Cnt = 1 } row := api.NewReceiptRow(params.Name, params.Cnt, params.Price, params.Taxgrp) if params.Disc > 0 { row.Disc = params.Disc } if params.Comment != "" { row.Comment = params.Comment } var pay api.ReceiptPay sum := (params.Price - params.Disc) * float64(params.Cnt) if params.PayType == PayTypeCard && params.CardParams != nil { pay = api.NewReceiptPayCard( sum, params.CardParams.Cardmask, params.CardParams.BankID, params.CardParams.RrnCode, params.CardParams.AuthCode, ) } else { pay = api.NewReceiptPayCash(sum, params.Comment) } return c.api.Sell(ctx, api.SellParams{ Cashier: c.cashier, Source: c.source, Rows: []api.ReceiptRow{row}, Pays: []api.ReceiptPay{pay}, Userinfo: params.Userinfo, }) } func (c *Client) SellWithTimeout(params SellParams, timeout time.Duration) (*api.SellResponse, error) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() return c.Sell(ctx, params) } func (c *Client) QuickSell(ctx context.Context, price float64) (*api.SellResponse, error) { return c.Sell(ctx, SellParams{ Price: price, }) } func (c *Client) QuickSellNamed(ctx context.Context, name string, price float64) (*api.SellResponse, error) { return c.Sell(ctx, SellParams{ Name: name, Price: price, }) }