package db import ( "context" "database/sql" "fmt" "git.nochill.in/nochill/naice_pos/util" "github.com/google/uuid" ) type SaleOrderProduct struct { ProductID uuid.UUID `json:"id"` ProductName string `json:"name"` Quantity float64 `json:"quantity"` Sub_total float64 `json:"sub_total"` Price float64 `json:"price"` } type SaleOrderTxParams struct { MerchantID uuid.UUID `json:"merchant_id"` CreatedBy uuid.UUID `json:"created_by"` // user_id CustomerID uuid.NullUUID `json:"customer_id"` Code string `json:"code"` IsPaid bool `json:"is_paid"` Total float64 `json:"total"` PaidNominal float64 `json:"paid_nominal"` Note sql.NullString `json:"note"` IsKeep bool `json:"is_keep"` Change float64 `json:"change"` Products []SaleOrderProduct `json:"products"` } type SaleOrderTxResult struct { SaleOrder SaleOrder `json:"sale_order"` SaleOrderDetail []SaleOrderDetail `json:"detail"` } func (store *SQLStore) SaleOrderTx(ctx context.Context, arg SaleOrderTxParams) (SaleOrderTxResult, error) { var result SaleOrderTxResult err := store.execTx(ctx, func(q *Queries) error { var err error result.SaleOrder, err = q.CreateSaleOrder(ctx, CreateSaleOrderParams{ MerchantID: arg.MerchantID, CustomerID: uuid.NullUUID{Valid: arg.CustomerID.Valid, UUID: arg.CustomerID.UUID}, Code: arg.Code, CreatedBy: arg.CreatedBy, IsPaid: arg.IsPaid, Total: arg.Total, PaidNominal: arg.PaidNominal, Note: sql.NullString{Valid: len(arg.Note.String) > 0, String: arg.Note.String}, IsKeep: arg.IsKeep, }) if err != nil { return err } for i := 0; i < len(arg.Products); i++ { product, err := q.GetStockForUpdateStock(ctx, arg.Products[i].ProductID) if err != nil { return err } profit := arg.Products[i].Price - product.SellingPrice saleOrderDetail, err := q.CreateSaleOrderDetail(ctx, CreateSaleOrderDetailParams{ SaleOrderID: result.SaleOrder.ID, ProductID: arg.Products[i].ProductID, ProductName: arg.Products[i].ProductName, Quantity: arg.Products[i].Quantity, SubTotal: arg.Products[i].Sub_total, ProductPrice: arg.Products[i].Price, Profit: profit, }) if err != nil { return err } result.SaleOrderDetail = append(result.SaleOrderDetail, saleOrderDetail) err = q.UpdateProductStock(ctx, UpdateProductStockParams{ ID: product.ID, Stock: product.Stock - arg.Products[i].Quantity, }) if err != nil { return err } _, err = q.CreateStockLogs(ctx, CreateStockLogsParams{ ProductID: arg.Products[i].ProductID, MerchantID: arg.MerchantID, CreatedBy: arg.CreatedBy, TransactionID: uuid.NullUUID{UUID: result.SaleOrder.ID, Valid: true}, TransactionActionType: "sale_order", TransactionDescription: fmt.Sprintf("Pengurangan stok produk %s dari penjualan dengan code %s", product.Name, arg.Code), Type: util.STOCK_LOG_OUT, SellingPrice: arg.Products[i].Price, PurchasePrice: product.PurchasePrice, Quantity: arg.Products[i].Quantity, }) if err != nil { return err } } return nil }) return result, err }