Files
go-vchasno-kassa/vchasno.go

265 lines
5.5 KiB
Go

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,
})
}