initial commit
This commit is contained in:
747
repositories/productRepository.go
Normal file
747
repositories/productRepository.go
Normal file
@@ -0,0 +1,747 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"nearle/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type ProductRepository interface {
|
||||
GetProductSubCategory(categoryID, tenantID int) ([]models.ProductSubCategory, error)
|
||||
GetProductCount(tenantID, categoryID, subcategoryID int, approve string) ([]models.Productcount, error)
|
||||
GetProductCategory() ([]models.ProductCategory, error)
|
||||
GetProductVariants(tenantID, subcategoryID int) ([]models.Productvariant, error)
|
||||
GetCatalougeProducts(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Products, error)
|
||||
GetProductStocks(tenantID, locationID string) ([]models.Productstocks, error)
|
||||
CreateProductStock(stocks []models.Productstock) error
|
||||
UpdateProductStatus(productIDs []int, status string) error
|
||||
CreateProduct(product models.Products) error
|
||||
UpdateProduct(product models.Products) error
|
||||
DeleteProduct(productID int) error
|
||||
GetStockStatement(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Productstockstatement, error)
|
||||
GetLocationProducts(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Locationproducts, error)
|
||||
GetLocationProductSummary(tenantID, locationID int) ([]models.ProductSummary, error)
|
||||
FetchFilteredProducts(categoryID, subcategoryID, productID, applocationID, tenantID, locationID int, keyword, productStatus, approve string, pageno, pagesize int) ([]models.Tenantproducts, error)
|
||||
GetProductByVariant(tenantid, variantid int) ([]models.Products, error)
|
||||
GetSubcategories(categoryID int) ([]models.Subcategory, error)
|
||||
GetProducts(params models.ProductFilter) ([]models.Products, error)
|
||||
GetTenantInfo(tenantID, applocationID int) (map[string]interface{}, error)
|
||||
UpdateProductLocation(input models.Productlocations) error
|
||||
CreateProductLocation(input []models.Productlocations) error
|
||||
CreateProductVariant(input models.Productvariant) error
|
||||
}
|
||||
|
||||
type productRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewProductRepository(db *gorm.DB) ProductRepository {
|
||||
return &productRepository{db: db}
|
||||
}
|
||||
|
||||
func (r *productRepository) GetProductSubCategory(categoryID, tenantID int) ([]models.ProductSubCategory, error) {
|
||||
var data []models.ProductSubCategory
|
||||
var query strings.Builder
|
||||
var args []interface{}
|
||||
|
||||
query.WriteString("SELECT * FROM productsubcategories WHERE 1=1")
|
||||
|
||||
if tenantID != 0 {
|
||||
query.WriteString(" AND tenantid = ?")
|
||||
args = append(args, tenantID)
|
||||
}
|
||||
if categoryID != 0 {
|
||||
query.WriteString(" AND categoryid = ?")
|
||||
args = append(args, categoryID)
|
||||
}
|
||||
|
||||
if err := r.db.Raw(query.String(), args...).Scan(&data).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// print()
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetProductCount(tenantid, categoryid, subcategory int, approve string) ([]models.Productcount, error) {
|
||||
var data []models.Productcount
|
||||
|
||||
baseQuery := `
|
||||
SELECT
|
||||
COUNT(*) AS total,
|
||||
SUM(CASE WHEN a.productstatus = 'available' THEN 1 ELSE 0 END) AS available,
|
||||
SUM(CASE WHEN a.productstatus = 'outofstock' THEN 1 ELSE 0 END) AS outofstock
|
||||
FROM products a
|
||||
WHERE 1 = 1
|
||||
`
|
||||
|
||||
var conditions []string
|
||||
var params []interface{}
|
||||
|
||||
if tenantid != 0 {
|
||||
conditions = append(conditions, "a.tenantid = ?")
|
||||
params = append(params, tenantid)
|
||||
}
|
||||
if categoryid != 0 {
|
||||
conditions = append(conditions, "a.categoryid = ?")
|
||||
params = append(params, categoryid)
|
||||
}
|
||||
if subcategory != 0 {
|
||||
conditions = append(conditions, "a.subcategoryid = ?")
|
||||
params = append(params, subcategory)
|
||||
}
|
||||
if approve != "" {
|
||||
conditions = append(conditions, "a.approve = ?")
|
||||
params = append(params, approve)
|
||||
}
|
||||
|
||||
if len(conditions) > 0 {
|
||||
baseQuery += " AND " + strings.Join(conditions, " AND ")
|
||||
}
|
||||
|
||||
if err := r.db.Raw(baseQuery, params...).Scan(&data).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
print(baseQuery)
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetProductCategory() ([]models.ProductCategory, error) {
|
||||
var data []models.ProductCategory
|
||||
q1 := `SELECT * FROM productcategories WHERE moduleid = 2 AND status = 'Active'`
|
||||
r.db.Raw(q1).Scan(&data)
|
||||
print(q1)
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetProductVariants(tenantID int, subcategoryID int) ([]models.Productvariant, error) {
|
||||
|
||||
var data []models.Productvariant
|
||||
|
||||
var query string
|
||||
var params []interface{}
|
||||
|
||||
query = `
|
||||
SELECT a.*, b.categoryname
|
||||
FROM productvariants a
|
||||
JOIN app_category b ON a.categoryid = b.categoryid
|
||||
WHERE a.tenantid = ?
|
||||
`
|
||||
params = append(params, tenantID)
|
||||
|
||||
if subcategoryID != 0 {
|
||||
query += " AND a.subcategoryid = ?"
|
||||
params = append(params, subcategoryID)
|
||||
}
|
||||
|
||||
r.db.Raw(query, params...).Scan(&data)
|
||||
|
||||
//print(query)
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetCatalougeProducts(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Products, error) {
|
||||
var data []models.Products
|
||||
|
||||
if pageno < 1 {
|
||||
pageno = 1
|
||||
}
|
||||
if pagesize < 1 {
|
||||
pagesize = 10
|
||||
}
|
||||
|
||||
offset := (pageno - 1) * pagesize
|
||||
params := []interface{}{locationID, tenantID}
|
||||
|
||||
// Base query
|
||||
query := `
|
||||
SELECT a.*
|
||||
FROM products a
|
||||
LEFT JOIN productlocations b
|
||||
ON a.productid = b.productid
|
||||
AND b.locationid = ?
|
||||
AND b.tenantid = a.tenantid
|
||||
WHERE a.approve = 1
|
||||
AND a.tenantid = ?
|
||||
AND b.productid IS NULL
|
||||
`
|
||||
|
||||
// Optional filters
|
||||
if subcategoryID != 0 {
|
||||
query += " AND a.subcategoryid = ?"
|
||||
params = append(params, subcategoryID)
|
||||
}
|
||||
|
||||
if keyword != "" {
|
||||
query += " AND LOWER(a.productname) LIKE ?"
|
||||
params = append(params, "%"+strings.ToLower(keyword)+"%")
|
||||
}
|
||||
|
||||
// Pagination
|
||||
query += " ORDER BY a.productid DESC LIMIT " + strconv.Itoa(pagesize) + " OFFSET " + strconv.Itoa(offset)
|
||||
|
||||
// Debug logs
|
||||
fmt.Println("Executing query:", query)
|
||||
fmt.Println("Params:", params)
|
||||
|
||||
// Execute query
|
||||
if err := r.db.Raw(query, params...).Scan(&data).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetProductStocks(tenantID, locationID string) ([]models.Productstocks, error) {
|
||||
var stocks []models.Productstocks
|
||||
var params []interface{}
|
||||
var conditions []string
|
||||
|
||||
query := `
|
||||
SELECT
|
||||
a.productid, a.tenantid, MAX(a.stockdate) AS stockdate, a.locationid, a.stocktype, a.maxquantity, a.minquantity, a.status,
|
||||
b.applocationid, b.categoryid, b.subcategoryid, b.catalogueid, b.addonid, b.discountid, b.pricingid,
|
||||
b.productname, b.productimage, b.productdesc, b.productsku, b.brandid, b.productbrand, b.productunit,
|
||||
b.unitvalue, b.toppicks, b.productcost, b.taxamount, b.taxpercent, b.producttax, b.productstock,
|
||||
b.productcombo, b.variants, b.retailprice, b.diffprice, b.diffpercent, b.othercost, b.approve,
|
||||
b.productstatus, b.created, b.updated, c.subcatname AS subcategoryname,
|
||||
SUM(CASE WHEN a.stocktype = 'in' THEN a.quantity ELSE 0 END) -
|
||||
SUM(CASE WHEN a.stocktype = 'out' THEN a.quantity ELSE 0 END) AS quantity
|
||||
FROM productstocks a
|
||||
JOIN products b ON a.productid = b.productid
|
||||
INNER JOIN productsubcategories c ON c.subcatid = b.subcategoryid
|
||||
`
|
||||
|
||||
if tenantID != "" {
|
||||
conditions = append(conditions, "a.tenantid = ?")
|
||||
params = append(params, tenantID)
|
||||
}
|
||||
|
||||
if locationID != "" {
|
||||
conditions = append(conditions, "a.locationid = ?")
|
||||
params = append(params, locationID)
|
||||
}
|
||||
|
||||
if len(conditions) > 0 {
|
||||
query += " WHERE " + strings.Join(conditions, " AND ")
|
||||
}
|
||||
|
||||
query += " GROUP BY a.productid"
|
||||
|
||||
if err := r.db.Raw(query, params...).Scan(&stocks).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return stocks, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) CreateProductStock(stocks []models.Productstock) error {
|
||||
return r.db.Table("productstocks").Create(&stocks).Error
|
||||
}
|
||||
|
||||
func (r *productRepository) UpdateProductStatus(productIDs []int, status string) error {
|
||||
return r.db.Table("products").
|
||||
Where("productid IN ?", productIDs).
|
||||
Update("productstatus", status).Error
|
||||
}
|
||||
|
||||
func (r *productRepository) CreateProduct(product models.Products) error {
|
||||
tx := r.db.Begin()
|
||||
|
||||
if err := tx.Create(&product).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *productRepository) UpdateProduct(product models.Products) error {
|
||||
tx := r.db.Begin()
|
||||
|
||||
if err := tx.Table("productlocations").
|
||||
Where("productid = ?", product.Productid).
|
||||
Select("status"). // only update 'approve' field
|
||||
Updates(product).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit().Error
|
||||
}
|
||||
|
||||
func (r *productRepository) DeleteProduct(productID int) error {
|
||||
tx := r.db.Begin()
|
||||
|
||||
if err := tx.Table("products").Where("productid = ?", productID).Delete(&models.Products{}).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetStockStatement(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Productstockstatement, error) {
|
||||
data := make([]models.Productstockstatement, 0)
|
||||
|
||||
if pageno < 1 {
|
||||
pageno = 1
|
||||
}
|
||||
if pagesize < 1 {
|
||||
pagesize = 10
|
||||
}
|
||||
|
||||
offset := (pageno - 1) * pagesize
|
||||
|
||||
params := []interface{}{tenantID, locationID}
|
||||
|
||||
query := `SELECT a.productid,a.productname,a.productimage,a.categoryid,a.subcategoryid,a.productunit,a.unitvalue,a.productcost,a.taxpercent,a.taxamount,a.retailprice,b.tenantid,b.locationid,
|
||||
COALESCE( SUM(CASE WHEN UPPER(c.stocktype) = 'IN' AND c.stockdate::date <= CURRENT_DATE THEN c.quantity ELSE 0 END) -
|
||||
SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' AND c.stockdate::date <= CURRENT_DATE THEN c.quantity ELSE 0 END),0 )
|
||||
AS opening,
|
||||
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'IN' AND c.stockdate::date = CURRENT_DATE THEN c.quantity ELSE 0 END), 0) AS credit,
|
||||
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' AND c.stockdate::date = CURRENT_DATE THEN c.quantity ELSE 0 END), 0) AS debit,
|
||||
COALESCE(
|
||||
( SUM(CASE WHEN UPPER(c.stocktype) = 'IN' AND c.stockdate::date < CURRENT_DATE THEN c.quantity ELSE 0 END) -
|
||||
SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' AND c.stockdate::date < CURRENT_DATE THEN c.quantity ELSE 0 END)
|
||||
) +
|
||||
SUM(CASE WHEN UPPER(c.stocktype) = 'IN' AND c.stockdate::date = CURRENT_DATE THEN c.quantity ELSE 0 END) -
|
||||
SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' AND c.stockdate::date = CURRENT_DATE THEN c.quantity ELSE 0 END),
|
||||
0
|
||||
) AS closing
|
||||
FROM products a
|
||||
JOIN productlocations b ON a.productid = b.productid AND a.tenantid = b.tenantid
|
||||
LEFT JOIN productstocks c ON a.productid = c.productid AND b.locationid = c.locationid AND b.tenantid = c.tenantid
|
||||
WHERE b.tenantid = ? AND b.locationid = ?`
|
||||
|
||||
if subcategoryID != 0 {
|
||||
query += " AND a.subcategoryid = ?"
|
||||
params = append(params, subcategoryID)
|
||||
}
|
||||
|
||||
if keyword != "" {
|
||||
query += " AND (CAST(a.productid AS TEXT) LIKE ? OR LOWER(a.productname) LIKE ?)"
|
||||
likeParam := "%" + strings.ToLower(keyword) + "%"
|
||||
params = append(params, likeParam, likeParam)
|
||||
}
|
||||
|
||||
query += `
|
||||
GROUP BY
|
||||
a.productid, a.productname, a.productimage,
|
||||
a.categoryid, a.subcategoryid, a.productunit,
|
||||
a.productcost, a.taxpercent, a.taxamount,
|
||||
a.retailprice, b.tenantid, b.locationid
|
||||
ORDER BY a.productid DESC LIMIT ` + strconv.Itoa(pagesize) + ` OFFSET ` + strconv.Itoa(offset)
|
||||
|
||||
if err := r.db.Raw(query, params...).Scan(&data).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
print(query)
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetLocationProducts(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Locationproducts, error) {
|
||||
var data []models.Locationproducts
|
||||
|
||||
if pageno < 1 {
|
||||
pageno = 1
|
||||
}
|
||||
if pagesize < 1 {
|
||||
pagesize = 10
|
||||
}
|
||||
offset := (pageno - 1) * pagesize
|
||||
|
||||
params := []interface{}{tenantID, locationID}
|
||||
|
||||
query := `SELECT a.*, b.productlocationid, b.status,
|
||||
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'IN' THEN c.quantity ELSE 0 END), 0) AS total_in,
|
||||
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' THEN c.quantity ELSE 0 END), 0) AS total_out,
|
||||
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'IN' THEN c.quantity ELSE 0 END) -
|
||||
SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' THEN c.quantity ELSE 0 END), 0) AS productstock
|
||||
FROM products a
|
||||
INNER JOIN productlocations b ON a.productid = b.productid AND a.tenantid = b.tenantid
|
||||
LEFT JOIN productstocks c ON a.productid = c.productid AND b.locationid = c.locationid AND a.tenantid = c.tenantid
|
||||
WHERE a.approve=1 AND a.tenantid = ? AND b.locationid = ?`
|
||||
|
||||
if subcategoryID != 0 {
|
||||
query += " AND a.subcategoryid = ?"
|
||||
params = append(params, subcategoryID)
|
||||
}
|
||||
|
||||
if keyword != "" {
|
||||
query += " AND LOWER(a.productname) LIKE ?"
|
||||
params = append(params, "%"+strings.ToLower(keyword)+"%")
|
||||
}
|
||||
|
||||
query += ` GROUP BY a.productid, a.productname, a.productimage, a.categoryid, a.subcategoryid,
|
||||
a.productunit, a.productcost, a.taxpercent, a.taxamount, a.retailprice,
|
||||
b.tenantid, b.locationid, b.productlocationid, b.status
|
||||
ORDER BY a.productid DESC LIMIT ? OFFSET ?`
|
||||
|
||||
params = append(params, pagesize, offset)
|
||||
|
||||
if err := r.db.Raw(query, params...).Scan(&data).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
print(query)
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetLocationProductSummary(tenantID, locationID int) ([]models.ProductSummary, error) {
|
||||
data := make([]models.ProductSummary, 0)
|
||||
|
||||
query := `
|
||||
SELECT
|
||||
a.subcatid AS subcategoryid,
|
||||
a.subcatname AS subcategroyname,
|
||||
a.image,
|
||||
COUNT(DISTINCT c.productid) AS productcount
|
||||
FROM productsubcategories a
|
||||
LEFT JOIN products b
|
||||
ON a.subcatid = b.subcategoryid
|
||||
AND b.approve = 1
|
||||
AND b.tenantid = ?
|
||||
LEFT JOIN productlocations c
|
||||
ON b.productid = c.productid
|
||||
AND c.tenantid = ?
|
||||
AND c.locationid = ?
|
||||
WHERE a.categoryid = 2
|
||||
GROUP BY a.subcatid, a.subcatname, a.image
|
||||
ORDER BY a.subcatid;
|
||||
`
|
||||
|
||||
// Only 3 params: tenantID for products, tenantID for locations, locationID
|
||||
params := []interface{}{tenantID, tenantID, locationID}
|
||||
|
||||
if err := r.db.Raw(query, params...).Scan(&data).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Correct "All" count: sum of only products that exist in this location
|
||||
total := 0
|
||||
for _, d := range data {
|
||||
total += d.Productcount
|
||||
}
|
||||
|
||||
all := models.ProductSummary{
|
||||
Subcategoryid: 0,
|
||||
Subcategroyname: "All",
|
||||
Productcount: total,
|
||||
}
|
||||
data = append([]models.ProductSummary{all}, data...)
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) FetchFilteredProducts(
|
||||
categoryID, subcategoryID, productID, applocationID, tenantID,
|
||||
locationID int, keyword, productStatus, approve string, pageno, pagesize int,
|
||||
) ([]models.Tenantproducts, error) {
|
||||
|
||||
offset := (pageno - 1) * pagesize
|
||||
results := make([]models.Tenantproducts, 0)
|
||||
|
||||
if tenantID == 0 {
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// Fetch tenant info
|
||||
var tenant models.TenantInfo
|
||||
if err := r.db.Table("tenants").Where("tenantid = ?", tenantID).First(&tenant).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Build product query
|
||||
var products []models.Products
|
||||
|
||||
query := r.db.
|
||||
Table("products a").
|
||||
Select(`
|
||||
a.*,
|
||||
b.status,
|
||||
c.categoryname,
|
||||
d.subcatname AS subcategoryname,
|
||||
ps.locationid,
|
||||
COALESCE(ps.quantity, 0) AS quantity
|
||||
`).
|
||||
Joins("LEFT JOIN productlocations b ON a.productid = b.productid").
|
||||
Joins("LEFT JOIN productcategories c ON a.categoryid = c.categoryid").
|
||||
Joins("LEFT JOIN productsubcategories d ON a.subcategoryid = d.subcatid").
|
||||
Joins(`
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
productid,
|
||||
locationid,
|
||||
SUM(CASE WHEN stocktype = 'in' THEN quantity ELSE 0 END) -
|
||||
SUM(CASE WHEN stocktype = 'out' THEN quantity ELSE 0 END) AS quantity
|
||||
FROM productstocks
|
||||
GROUP BY productid, locationid
|
||||
) ps ON ps.productid = a.productid
|
||||
`).
|
||||
Where("a.tenantid = ?", tenantID).
|
||||
Order("a.productid DESC")
|
||||
|
||||
if categoryID != 0 {
|
||||
query = query.Where("a.categoryid = ?", categoryID)
|
||||
}
|
||||
if subcategoryID != 0 {
|
||||
query = query.Where("a.subcategoryid = ?", subcategoryID)
|
||||
}
|
||||
if productID != 0 {
|
||||
query = query.Where("a.productid = ?", productID)
|
||||
}
|
||||
if productStatus != "" {
|
||||
query = query.Where("a.productstatus = ?", productStatus)
|
||||
}
|
||||
if locationID != 0 {
|
||||
query = query.Where("e.locationid = ?", locationID)
|
||||
}
|
||||
if approve != "" {
|
||||
query = query.Where("a.approve = ?", approve)
|
||||
}
|
||||
|
||||
if keyword != "" {
|
||||
like := "%" + strings.ToLower(keyword) + "%"
|
||||
query = query.Where(
|
||||
r.db.Where("LOWER(a.productname) LIKE ?", like).
|
||||
Or("LOWER(a.unitvalue) LIKE ?", like).
|
||||
Or("LOWER(CAST(a.productcost AS TEXT)) LIKE ?", like),
|
||||
)
|
||||
}
|
||||
|
||||
if pagesize > 0 && offset >= 0 {
|
||||
query = query.Limit(pagesize).Offset(offset)
|
||||
}
|
||||
|
||||
if err := query.Scan(&products).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if products == nil {
|
||||
products = []models.Products{}
|
||||
}
|
||||
|
||||
results = append(results, models.Tenantproducts{
|
||||
Tenant: tenant,
|
||||
Products: products,
|
||||
})
|
||||
|
||||
print(query)
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetProductByVariant(tenantid, variantid int) ([]models.Products, error) {
|
||||
|
||||
var data []models.Products
|
||||
|
||||
err := r.db.
|
||||
Table("products p").
|
||||
Select(`
|
||||
p.*,
|
||||
c.categoryname,
|
||||
d.subcatname AS subcategoryname,
|
||||
COALESCE(pd.discountvalue, 0) AS discountvalue,
|
||||
pd.discountid
|
||||
`).
|
||||
Joins("LEFT JOIN productcategories c ON p.categoryid = c.categoryid").
|
||||
Joins("LEFT JOIN productsubcategories d ON p.subcategoryid = d.subcatid").
|
||||
Joins("LEFT JOIN productdiscounts pd ON pd.productid = p.productid").
|
||||
Where("p.tenantid = ? AND p.variants = ?", tenantid, variantid).
|
||||
Order("p.productid DESC").
|
||||
Scan(&data).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) GetSubcategories(categoryID int) ([]models.Subcategory, error) {
|
||||
var subcats []models.Subcategory
|
||||
err := r.db.Table("productsubcategories").
|
||||
Where("categoryid = ?", categoryID).
|
||||
Find(&subcats).Error
|
||||
return subcats, err
|
||||
}
|
||||
|
||||
func (r *productRepository) GetProducts(params models.ProductFilter) ([]models.Products, error) {
|
||||
var products []models.Products
|
||||
|
||||
q := r.db.Table("products a").
|
||||
Joins("LEFT JOIN productlocations pl ON pl.productid = a.productid").
|
||||
Joins("LEFT JOIN productdiscounts pd ON pd.productid = a.productid").
|
||||
Joins("LEFT JOIN productcategories c ON a.categoryid = c.categoryid").
|
||||
Where("a.categoryid = ?", params.CategoryID)
|
||||
|
||||
if params.TenantID > 0 {
|
||||
q = q.Where("a.tenantid = ?", params.TenantID)
|
||||
}
|
||||
if params.LocationID > 0 {
|
||||
q = q.Where("pl.locationid = ?", params.LocationID)
|
||||
}
|
||||
if params.AppLocationID > 0 {
|
||||
q = q.Where("a.applocationid = ?", params.AppLocationID)
|
||||
}
|
||||
if params.ProductID > 0 {
|
||||
q = q.Where("a.productid = ?", params.ProductID)
|
||||
}
|
||||
if params.Keyword != "" {
|
||||
like := "%" + strings.ToLower(params.Keyword) + "%"
|
||||
q = q.Where(
|
||||
r.db.Where("LOWER(a.productname) LIKE ?", like).
|
||||
Or("LOWER(a.unitvalue) LIKE ?", like).
|
||||
Or("LOWER(CAST(a.productcost AS TEXT)) LIKE ?", like),
|
||||
)
|
||||
}
|
||||
|
||||
err := q.Select(`
|
||||
a.*,
|
||||
COALESCE(pd.discountvalue, 0) AS discountvalue
|
||||
`).Find(&products).Error
|
||||
|
||||
return products, err
|
||||
}
|
||||
|
||||
func (r *productRepository) GetTenantInfo(tenantID, applocationID int) (map[string]interface{}, error) {
|
||||
var tenant struct {
|
||||
Tenantname string
|
||||
Address string
|
||||
Licenseno string
|
||||
Primaryemail string
|
||||
Primarycontact string
|
||||
Locationname string
|
||||
Pickuplocationid int
|
||||
Suburb string
|
||||
City string
|
||||
Latitude string
|
||||
Longitude string
|
||||
Postcode string
|
||||
}
|
||||
|
||||
err := r.db.Raw(`
|
||||
SELECT t.tenantname, t.address, t.licenseno, t.primaryemail, t.primarycontact,
|
||||
l.locationid AS pickuplocationid, l.suburb, l.city, l.latitude, l.longitude, l.postcode,
|
||||
a.locationname
|
||||
FROM tenants t
|
||||
LEFT JOIN tenantlocations l ON t.tenantid = l.tenantid
|
||||
LEFT JOIN app_location a ON l.applocationid = a.applocationid
|
||||
WHERE t.tenantid = ? AND t.applocationid = ?
|
||||
LIMIT 1
|
||||
`, tenantID, applocationID).Scan(&tenant).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"tenantname": tenant.Tenantname,
|
||||
"address": tenant.Address,
|
||||
"licenseno": tenant.Licenseno,
|
||||
"primaryemail": tenant.Primaryemail,
|
||||
"primarycontact": tenant.Primarycontact,
|
||||
"locationname": tenant.Locationname,
|
||||
"pickuplocationid": tenant.Pickuplocationid,
|
||||
"suburb": tenant.Suburb,
|
||||
"city": tenant.City,
|
||||
"pickuplat": tenant.Latitude,
|
||||
"pickuplong": tenant.Longitude,
|
||||
"postcode": tenant.Postcode,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *productRepository) UpdateProductLocation(input models.Productlocations) error {
|
||||
tx := r.db.Begin()
|
||||
|
||||
t1 := tx.Where("productlocationid = ?", input.Productlocationid).Updates(&input)
|
||||
if t1.Error != nil {
|
||||
tx.Rollback()
|
||||
return t1.Error
|
||||
}
|
||||
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *productRepository) CreateProductLocation(input []models.Productlocations) error {
|
||||
var stk []models.Productstock
|
||||
tx := r.db.Begin()
|
||||
|
||||
// Insert or update product location
|
||||
if err := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "tenantid"}, {Name: "locationid"}, {Name: "productid"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"price", "minquantity", "maxquantity"}),
|
||||
}).Create(&input).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// Prepare product stock entries
|
||||
for _, loc := range input {
|
||||
if loc.Quantity > 0 {
|
||||
stk = append(stk, models.Productstock{
|
||||
Tenantid: loc.Tenantid,
|
||||
Stockdate: time.Now(),
|
||||
Locationid: loc.Locationid,
|
||||
Productid: loc.Productid,
|
||||
Quantity: loc.Quantity,
|
||||
Stocktype: loc.Stocktype,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Insert stock records if available
|
||||
if len(stk) > 0 {
|
||||
if err := tx.Create(&stk).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Commit transaction
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *productRepository) CreateProductVariant(input models.Productvariant) error {
|
||||
tx := r.db.Begin()
|
||||
|
||||
if err := tx.Create(&input).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user