Documentation
¶
Index ¶
- type AddOrderItemDTO
- type ApplyOrderDiscountDTO
- type CheckoutDTO
- type CloseSessionDTO
- type CreateBranchDTO
- type CreateCompanyDTO
- type CreateCustomerDTO
- type CreateDiscountDTO
- type CreateExpenseDTO
- type CreateOrderDTO
- type CreatePOSStationDTO
- type CreateProductDTO
- type CreateSupplierDTO
- type CreateUserDTO
- type FindOrCreateCustomerDTO
- type InventoryReportQuery
- type LoginDTO
- type OpenSessionDTO
- type PLReportQuery
- type PaginationDTO
- type PaginationResults
- type PaymentDTO
- type RecipeComponentDTO
- type RecipeDTO
- type RecipeOverheadDTO
- type RecordStockCountDTO
- type RecordStockMovementDTO
- type RecordSupplierPaymentDTO
- type RefreshDTO
- type RegisterDTO
- type ReturnItemDTO
- type ReturnOrderDTO
- type SalesReportQuery
- type SetRecipeDTO
- type UpdateBranchDTO
- type UpdateCompanyDTO
- type UpdateCustomerDTO
- type UpdateDiscountDTO
- type UpdatePOSStationDTO
- type UpdateProductDTO
- type UpdateSupplierDTO
- type UpdateUserDTO
- type VoidOrderDTO
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AddOrderItemDTO ¶
type AddOrderItemDTO struct {
ProductID uuid.UUID `json:"product_id" validate:"required"`
Quantity int64 `json:"quantity" validate:"required,min=1"`
DiscountID *uuid.UUID `json:"discount_id"`
AdHocDiscountAmount int64 `json:"ad_hoc_discount_amount"`
}
AddOrderItemDTO is the request body for POST /api/v1/orders/:id/items.
type ApplyOrderDiscountDTO ¶
type ApplyOrderDiscountDTO struct {
DiscountID *uuid.UUID `json:"discount_id"`
AdHocDiscountAmount int64 `json:"ad_hoc_discount_amount"`
// CouponCode, when non-empty, resolves the discount by its
// cashier-entered code instead of DiscountID. Mutually exclusive with
// DiscountID/AdHocDiscountAmount.
CouponCode string `json:"coupon_code"`
}
ApplyOrderDiscountDTO is the request body for POST /api/v1/orders/:id/discount.
type CheckoutDTO ¶
type CheckoutDTO struct {
Payments []PaymentDTO `json:"payments" validate:"required,min=1,dive"`
}
CheckoutDTO is the request body for POST /api/v1/orders/:id/checkout.
type CloseSessionDTO ¶
type CloseSessionDTO struct {
DeclaredCash int64 `json:"declared_cash" validate:"min=0"`
}
CloseSessionDTO is the request body for POST /api/v1/sessions/:id/close.
type CreateBranchDTO ¶
type CreateBranchDTO struct {
CompanyID uuid.UUID `json:"company_id" validate:"required"`
Name string `json:"name" validate:"required"`
Address string `json:"address" validate:"required"`
}
CreateBranchDTO holds the payload to create a new branch. For owners, CompanyID must be supplied explicitly. For managers and cashiers it is extracted from their JWT and injected by the handler.
type CreateCompanyDTO ¶
type CreateCompanyDTO struct {
Name string `json:"name" validate:"required"`
Handle string `json:"handle" validate:"omitempty,min=3,max=50"`
Currency string `json:"currency" validate:"required,len=3"`
}
CreateCompanyDTO holds the payload to create a new company. Currency must be a 3-letter uppercase ISO 4217 code (e.g. "USD", "IDR"). Handle is a URL slug (lowercase alphanum + hyphens, 3-50 chars); auto-generated from Name if empty. Must be globally unique.
type CreateCustomerDTO ¶
type CreateCustomerDTO struct {
CompanyID uuid.UUID `json:"company_id" validate:"required"`
Name string `json:"name" validate:"required"`
Email string `json:"email" validate:"omitempty,email"`
Phone string `json:"phone" validate:"omitempty"`
}
CreateCustomerDTO holds the payload to register a new customer.
type CreateDiscountDTO ¶
type CreateDiscountDTO struct {
CompanyID uuid.UUID `json:"company_id" validate:"required"`
Name string `json:"name" validate:"required"`
Type string `json:"type" validate:"required,oneof=fixed percentage"`
Value int64 `json:"value" validate:"required,min=1"`
// Code, when non-empty, makes this discount redeemable by a
// cashier-entered coupon code instead of being picked from the list.
Code string `json:"code"`
// ValidFrom/ValidUntil optionally bound when this discount can be
// applied. Nil means no bound on that side.
ValidFrom *time.Time `json:"valid_from"`
ValidUntil *time.Time `json:"valid_until"`
// MaxRedemptions optionally caps how many orders may redeem this
// discount in total. Nil means unlimited.
MaxRedemptions *int `json:"max_redemptions"`
}
CreateDiscountDTO is the request body for POST /api/v1/discounts.
type CreateExpenseDTO ¶
type CreateExpenseDTO struct {
CompanyID uuid.UUID `json:"company_id" validate:"required"`
Description string `json:"description" validate:"required"`
Amount int64 `json:"amount" validate:"required,min=1"`
AccountCode string `json:"account_code"` // COA debit account; defaults to "6000"
PaidFrom string `json:"paid_from"` // COA credit account; defaults to "1000"
}
CreateExpenseDTO is the request body for POST /expenses.
type CreateOrderDTO ¶
type CreateOrderDTO struct {
SessionID uuid.UUID `json:"session_id" validate:"required"`
CustomerID *uuid.UUID `json:"customer_id"`
}
CreateOrderDTO is the request body for POST /api/v1/orders.
type CreatePOSStationDTO ¶
type CreatePOSStationDTO struct {
CompanyID uuid.UUID `json:"company_id" validate:"required"`
BranchID uuid.UUID `json:"branch_id" validate:"required"`
Name string `json:"name" validate:"required"`
}
CreatePOSStationDTO holds the payload to register a new POS terminal.
type CreateProductDTO ¶
type CreateProductDTO struct {
CompanyID uuid.UUID `json:"company_id" validate:"required"`
Type string `json:"type" validate:"required,oneof=ingredient simple recipe"`
Name string `json:"name" validate:"required"`
BasePrice int64 `json:"base_price" validate:"min=0"`
Unit string `json:"unit" validate:"required"`
LowStockThreshold *int64 `json:"low_stock_threshold" validate:"omitempty,min=0"`
SKU string `json:"sku" validate:"omitempty,max=64"`
InitialQuantity *float64 `json:"initial_quantity" validate:"omitempty,gt=0"`
InitialUnitCost *int64 `json:"initial_unit_cost" validate:"omitempty,min=1"`
}
CreateProductDTO holds the payload to create a new product. LowStockThreshold uses a pointer so the service can fall back to its default (20) when the field is omitted, rather than treating an omitted field the same as an explicit 0. SKU is optional — left blank, the service defaults it to the product's own generated ID.
InitialQuantity and InitialUnitCost are optional and must both be set or both omitted — the service records them as one procurement movement (never an expense; see service.ProductService.Create), only valid for simple/ingredient products. Tags are deliberately lenient (omitempty): the both-or-neither rule and the type restriction are enforced in the service layer, not here, because the SSR web form path builds this DTO from raw form values without running validator tags at all.
type CreateSupplierDTO ¶
type CreateSupplierDTO struct {
CompanyID uuid.UUID `json:"company_id" validate:"required"`
Name string `json:"name" validate:"required"`
Contact string `json:"contact" validate:"omitempty"`
Phone string `json:"phone" validate:"omitempty"`
Email string `json:"email" validate:"omitempty,email"`
Address string `json:"address" validate:"omitempty"`
}
CreateSupplierDTO holds the payload to register a new supplier.
type CreateUserDTO ¶
type CreateUserDTO struct {
Email string `json:"email" validate:"required,email"`
Name string `json:"name" validate:"required"`
Password string `json:"password" validate:"required,min=8"`
Role string `json:"role" validate:"required,oneof=owner manager cashier"`
CompanyID *uuid.UUID `json:"company_id"`
}
CreateUserDTO holds the payload required to register a new user. CompanyID is required when Role is "manager" or "cashier"; validated in UserService.
type FindOrCreateCustomerDTO ¶ added in v0.1.2
FindOrCreateCustomerDTO looks up a customer by email or phone within a company; if no match exists, a new customer is created from Name/Email/Phone.
type InventoryReportQuery ¶
InventoryReportQuery binds query parameters for GET /api/v1/reports/inventory.
type LoginDTO ¶
type LoginDTO struct {
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required"`
}
LoginDTO holds credentials for the login endpoint.
type OpenSessionDTO ¶
type OpenSessionDTO struct {
StationID uuid.UUID `json:"station_id" validate:"required"`
OpeningCash int64 `json:"opening_cash" validate:"min=0"`
}
OpenSessionDTO is the request body for POST /api/v1/sessions.
type PLReportQuery ¶
type PLReportQuery struct {
CompanyID uuid.UUID `query:"company_id" validate:"required"`
From string `query:"from" validate:"required"` // YYYY-MM-DD
To string `query:"to" validate:"required"` // YYYY-MM-DD
}
PLReportQuery binds query parameters for GET /api/v1/reports/pnl.
type PaginationDTO ¶
type PaginationDTO struct {
Page int32 `query:"page" validate:"omitempty,min=1"`
PerPage int32 `query:"per_page" validate:"omitempty,min=1,max=100"`
Search string `query:"search" validate:"omitempty,max=100"`
}
PaginationDTO holds pagination query parameters from HTTP requests.
func (*PaginationDTO) Limit ¶
func (d *PaginationDTO) Limit() int32
Limit returns the number of items per page, defaulting to 20.
func (*PaginationDTO) Offset ¶
func (d *PaginationDTO) Offset() int32
Offset returns the row offset for the current page.
type PaginationResults ¶
type PaginationResults[T any] struct { Page int `json:"page"` PerPage int `json:"per_page"` TotalItems int `json:"total_items"` Items []T `json:"items"` }
PaginationResults wraps a page of results with metadata.
type PaymentDTO ¶
type PaymentDTO struct {
Amount int64 `json:"amount" validate:"required,min=1"`
Method string `json:"method" validate:"required"`
// TenderedAmount is optional and only meaningful for cash: what the
// customer physically handed over, if more than Amount (the rest is
// change). Must be >= Amount when present.
TenderedAmount *int64 `json:"tendered_amount,omitempty" validate:"omitempty,gtefield=Amount"`
}
PaymentDTO describes a single payment leg within a CheckoutDTO.
type RecipeComponentDTO ¶
type RecipeComponentDTO struct {
IngredientID uuid.UUID `json:"ingredient_id" validate:"required"`
Quantity float64 `json:"quantity" validate:"required,gt=0"`
}
RecipeComponentDTO is one component entry in a SetRecipeDTO.
type RecipeDTO ¶
type RecipeDTO struct {
Components []model.RecipeComponent `json:"components"`
Overheads []model.RecipeOverhead `json:"overheads"`
}
RecipeDTO is the response body for GET /products/:id/recipe.
type RecipeOverheadDTO ¶
type RecipeOverheadDTO struct {
Description string `json:"description" validate:"required"`
Cost int64 `json:"cost" validate:"required,min=1"`
}
RecipeOverheadDTO is one overhead entry in a SetRecipeDTO.
type RecordStockCountDTO ¶ added in v0.1.4
type RecordStockCountDTO struct {
ProductID uuid.UUID `json:"product_id" validate:"required"`
CountedQuantity float64 `json:"counted_quantity" validate:"gte=0"`
}
RecordStockCountDTO is a physical count to reconcile against current system stock — the caller doesn't compute the delta or pick a direction; the service works out whether that's an adjustment_up or adjustment_down (or no discrepancy at all).
type RecordStockMovementDTO ¶
type RecordStockMovementDTO struct {
ProductID uuid.UUID `json:"product_id" validate:"required"`
Reason string `json:"reason" validate:"required,oneof=procurement opening_balance waste adjustment_up adjustment_down"`
Quantity float64 `json:"quantity" validate:"required,gt=0"`
UnitCost *int64 `json:"unit_cost" validate:"omitempty,min=1"`
Notes string `json:"notes"`
SupplierID *uuid.UUID `json:"supplier_id" validate:"omitempty"`
}
RecordStockMovementDTO is the request body for POST /stock-movements. Quantity is always positive; the service applies the sign based on Reason.
type RecordSupplierPaymentDTO ¶
type RecordSupplierPaymentDTO struct {
Amount int64 `json:"amount" validate:"required,min=1"`
Notes string `json:"notes"`
PaidFrom string `json:"paid_from"` // COA credit account; defaults to "1000"
}
RecordSupplierPaymentDTO is the request body for POST /suppliers/:id/payments.
type RefreshDTO ¶
type RefreshDTO struct {
RefreshToken string `json:"refresh_token" validate:"required"`
}
RefreshDTO holds the refresh token for the token-refresh endpoint.
type RegisterDTO ¶
type RegisterDTO struct {
Name string `json:"name" validate:"required"`
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required,min=8"`
}
RegisterDTO holds the payload for the unauthenticated owner-registration endpoint. Role is always "owner"; owners never get a company_id of their own (see model.User) — they create/own companies via companies.owner_id instead, starting at /setup/companies/new.
type ReturnItemDTO ¶
type ReturnItemDTO struct {
OrderItemID uuid.UUID `json:"order_item_id" validate:"required"`
Quantity int64 `json:"quantity" validate:"required,min=1"`
}
ReturnItemDTO describes a single item line within a ReturnOrderDTO.
type ReturnOrderDTO ¶
type ReturnOrderDTO struct {
Items []ReturnItemDTO `json:"items" validate:"required,min=1,dive"`
RefundMethod string `json:"refund_method" validate:"required"`
Reason string `json:"reason"`
}
ReturnOrderDTO is the request body for POST /api/v1/orders/:id/return.
type SalesReportQuery ¶
type SalesReportQuery struct {
CompanyID uuid.UUID `query:"company_id" validate:"required"`
From string `query:"from" validate:"required"` // YYYY-MM-DD
To string `query:"to" validate:"required"` // YYYY-MM-DD
GroupBy string `query:"group_by"` // day|week|month (default: day)
TopN int `query:"top_n"` // default 10
}
SalesReportQuery binds query parameters for GET /api/v1/reports/sales.
type SetRecipeDTO ¶
type SetRecipeDTO struct {
Components []RecipeComponentDTO `json:"components" validate:"required"`
Overheads []RecipeOverheadDTO `json:"overheads"`
}
SetRecipeDTO is the body for PUT /products/:id/recipe. It atomically replaces all components and overheads for the recipe.
type UpdateBranchDTO ¶
type UpdateBranchDTO struct {
Name string `json:"name" validate:"omitempty"`
Address string `json:"address" validate:"omitempty"`
}
UpdateBranchDTO holds the payload to update a branch's details.
type UpdateCompanyDTO ¶
type UpdateCompanyDTO struct {
Name string `json:"name" validate:"omitempty"`
Handle string `json:"handle" validate:"omitempty,min=3,max=50"`
Currency string `json:"currency" validate:"omitempty,len=3"`
LogoFileID *uuid.UUID `json:"logo_file_id" validate:"omitempty"`
}
UpdateCompanyDTO holds the payload to update a company's details. LogoFileID is a pointer so "not provided" (leave the logo untouched) can be distinguished from an explicit change: pointing at a real file ID sets the logo, pointing at uuid.Nil clears it (uuid.Nil is never a real file ID, so it's safe to use as the "remove" sentinel here).
type UpdateCustomerDTO ¶
type UpdateCustomerDTO struct {
Name string `json:"name" validate:"omitempty"`
Email string `json:"email" validate:"omitempty,email"`
Phone string `json:"phone" validate:"omitempty"`
}
UpdateCustomerDTO holds the payload to update a customer's details.
type UpdateDiscountDTO ¶
type UpdateDiscountDTO struct {
Name string `json:"name"`
Value int64 `json:"value" validate:"omitempty,min=1"`
Active *bool `json:"active"`
Code string `json:"code"`
ValidFrom *time.Time `json:"valid_from"`
ValidUntil *time.Time `json:"valid_until"`
MaxRedemptions *int `json:"max_redemptions"`
}
UpdateDiscountDTO is the request body for PUT /api/v1/discounts/:id.
type UpdatePOSStationDTO ¶
type UpdatePOSStationDTO struct {
Name string `json:"name" validate:"omitempty"`
}
UpdatePOSStationDTO holds the payload to rename a POS station.
type UpdateProductDTO ¶
type UpdateProductDTO struct {
Name string `json:"name" validate:"omitempty"`
BasePrice *int64 `json:"base_price" validate:"omitempty,min=0"`
Unit string `json:"unit" validate:"omitempty"`
LowStockThreshold *int64 `json:"low_stock_threshold" validate:"omitempty,min=0"`
SKU *string `json:"sku" validate:"omitempty,max=64"`
ImageFileID *uuid.UUID `json:"image_file_id" validate:"omitempty"`
}
UpdateProductDTO holds the payload to update a product's mutable fields. Type is intentionally absent — it is immutable after creation. BasePrice and LowStockThreshold use pointers so the service can distinguish "explicitly set to 0" from "field not provided". SKU is also a pointer, but unlike the others a non-nil-but-blank value has meaning: it resets SKU back to the product's own ID rather than leaving it untouched. ImageFileID follows the same tri-state convention as UpdateCompanyDTO.LogoFileID: nil leaves it untouched, uuid.Nil clears it, a real file ID sets it.
type UpdateSupplierDTO ¶
type UpdateSupplierDTO struct {
Name string `json:"name" validate:"omitempty"`
Contact string `json:"contact" validate:"omitempty"`
Phone string `json:"phone" validate:"omitempty"`
Email string `json:"email" validate:"omitempty,email"`
Address string `json:"address" validate:"omitempty"`
}
UpdateSupplierDTO holds the payload to update a supplier's details.
type UpdateUserDTO ¶
type UpdateUserDTO struct {
Email string `json:"email" validate:"omitempty,email"`
Name string `json:"name" validate:"omitempty"`
}
UpdateUserDTO holds the payload for updating a user's profile.
type VoidOrderDTO ¶
type VoidOrderDTO struct {
Reason string `json:"reason"`
}
VoidOrderDTO is the request body for POST /api/v1/orders/:id/void.