Merge remote-tracking branch 'origin/dev_1.4.1'
This commit is contained in:
commit
86f2ddc6f8
|
@ -35,6 +35,9 @@ const (
|
||||||
SystemOut = 5 // 系统出库
|
SystemOut = 5 // 系统出库
|
||||||
CheckOut = 6 // 盘点出库
|
CheckOut = 6 // 盘点出库
|
||||||
OnSale = 7 // 销售锁定中
|
OnSale = 7 // 销售锁定中
|
||||||
|
|
||||||
|
PurchasePrice = "erp:stock:stockDetails:list:purchasePrice" // 入库采购价
|
||||||
|
EmployeeCostPrice = "erp:stock:stockDetails:list:employeeCostPrice" // 入库员工成本价
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErpStock 库存列表
|
// ErpStock 库存列表
|
||||||
|
@ -1142,7 +1145,7 @@ func GenerateSerialCode(categoryID uint32) (string, error) {
|
||||||
serialCode := categoryStr + dateStr + randomStr
|
serialCode := categoryStr + dateStr + randomStr
|
||||||
|
|
||||||
// 检查生成的串码是否已存在 todo 是否需要判断状态,采购退货的可以重复?
|
// 检查生成的串码是否已存在 todo 是否需要判断状态,采购退货的可以重复?
|
||||||
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET(%s, imei) > 0 ", serialCode))
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET('%s', imei) > 0 ", serialCode))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("exist sn err")
|
logger.Error("exist sn err")
|
||||||
}
|
}
|
||||||
|
@ -1446,25 +1449,62 @@ func ErpCommodityListExport(list []ErpCommodity) (string, error) {
|
||||||
return url + fileName, nil
|
return url + fileName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断是否有入库采购价、入库员工成本价的权限
|
||||||
|
func checkRoleMenu(c *gin.Context, menuName string) (bool, error) {
|
||||||
|
if tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员" {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var sysMenu Menu
|
||||||
|
err := orm.Eloquent.Table("sys_menu").Raw("select * from sys_menu where permission = ?",
|
||||||
|
menuName).Scan(&sysMenu).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("get sys_menu err:", err)
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
roleId := tools.GetRoleId(c)
|
||||||
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM sys_role_menu WHERE `menu_id`='%d' "+
|
||||||
|
"and `role_id`='%d'", sysMenu.MenuId, roleId))
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("checkRoleMenu QueryRecordExist err:", err)
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return exist, nil
|
||||||
|
}
|
||||||
|
|
||||||
// InventoryDetailListExport 导出库存商品列表
|
// InventoryDetailListExport 导出库存商品列表
|
||||||
func InventoryDetailListExport(list []ErpStockCommodity) (string, error) {
|
func InventoryDetailListExport(list []ErpStockCommodity, exportPurchasePrice bool, exportStaffCostPrice bool) (string, error) {
|
||||||
file := excelize.NewFile()
|
file := excelize.NewFile()
|
||||||
streamWriter, err := file.NewStreamWriter("Sheet1")
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
url := ExportUrl
|
url := ExportUrl
|
||||||
fileName := time.Now().Format(TimeFormat) + "商品" + ".xlsx"
|
fileName := time.Now().Format(TimeFormat) + "商品" + ".xlsx"
|
||||||
fmt.Println("url fileName:", url+fileName)
|
fmt.Println("url fileName:", url+fileName)
|
||||||
|
|
||||||
|
// 设置标题行
|
||||||
title := []interface{}{"商品编号", "商品名称", "商品分类", "是否串码", "商品串码", "所属门店", "供应商", "首次入库时间", "首次入库方式",
|
title := []interface{}{"商品编号", "商品名称", "商品分类", "是否串码", "商品串码", "所属门店", "供应商", "首次入库时间", "首次入库方式",
|
||||||
"首次入库订单编号", "最近入库时间", "入库采购价", "入库员工成本价", "最近库龄", "总库龄", "当前状态", "备注"}
|
"首次入库订单编号", "最近入库时间"}
|
||||||
|
|
||||||
|
if exportPurchasePrice {
|
||||||
|
title = append(title, "入库采购价")
|
||||||
|
}
|
||||||
|
if exportStaffCostPrice {
|
||||||
|
title = append(title, "入库员工成本价")
|
||||||
|
}
|
||||||
|
|
||||||
|
title = append(title, "最近库龄", "总库龄", "当前状态", "备注")
|
||||||
|
|
||||||
cell, _ := excelize.CoordinatesToCellName(1, 1)
|
cell, _ := excelize.CoordinatesToCellName(1, 1)
|
||||||
if err = streamWriter.SetRow(cell, title); err != nil {
|
if err = streamWriter.SetRow(cell, title); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
var row []interface{}
|
|
||||||
for rowId := 0; rowId < len(list); rowId++ {
|
for rowId := 0; rowId < len(list); rowId++ {
|
||||||
isIMEIType := "是"
|
isIMEIType := "是"
|
||||||
if list[rowId].IMEIType == 1 {
|
if list[rowId].IMEIType == 1 {
|
||||||
|
@ -1492,7 +1532,7 @@ func InventoryDetailListExport(list []ErpStockCommodity) (string, error) {
|
||||||
state = "盘点出库"
|
state = "盘点出库"
|
||||||
}
|
}
|
||||||
|
|
||||||
row = []interface{}{
|
row := []interface{}{
|
||||||
list[rowId].CommoditySerialNumber,
|
list[rowId].CommoditySerialNumber,
|
||||||
list[rowId].ErpCommodityName,
|
list[rowId].ErpCommodityName,
|
||||||
list[rowId].ErpCategoryName,
|
list[rowId].ErpCategoryName,
|
||||||
|
@ -1504,23 +1544,36 @@ func InventoryDetailListExport(list []ErpStockCommodity) (string, error) {
|
||||||
storageType,
|
storageType,
|
||||||
list[rowId].OriginalSn,
|
list[rowId].OriginalSn,
|
||||||
list[rowId].StockTime,
|
list[rowId].StockTime,
|
||||||
list[rowId].WholesalePrice,
|
}
|
||||||
list[rowId].WholesalePrice + list[rowId].StaffCostPrice,
|
|
||||||
list[rowId].Age,
|
// 控制是否导出入库采购价和入库员工成本价
|
||||||
list[rowId].AllAge,
|
if exportPurchasePrice {
|
||||||
state,
|
row = append(row, list[rowId].WholesalePrice)
|
||||||
list[rowId].Remark}
|
}
|
||||||
|
if exportStaffCostPrice {
|
||||||
|
row = append(row, list[rowId].WholesalePrice+list[rowId].StaffCostPrice)
|
||||||
|
}
|
||||||
|
|
||||||
|
row = append(row, list[rowId].Age)
|
||||||
|
row = append(row, list[rowId].AllAge)
|
||||||
|
row = append(row, state)
|
||||||
|
row = append(row, list[rowId].Remark)
|
||||||
|
|
||||||
cell, _ := excelize.CoordinatesToCellName(1, rowId+2)
|
cell, _ := excelize.CoordinatesToCellName(1, rowId+2)
|
||||||
if err := streamWriter.SetRow(cell, row); err != nil {
|
if err := streamWriter.SetRow(cell, row); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := streamWriter.Flush(); err != nil {
|
if err := streamWriter.Flush(); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
|
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
|
||||||
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
|
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
return url + fileName, nil
|
return url + fileName, nil
|
||||||
}
|
}
|
||||||
|
@ -1573,6 +1626,7 @@ type ErpStockListReq struct {
|
||||||
SerialNumber string `json:"serial_number"` // 商品编号
|
SerialNumber string `json:"serial_number"` // 商品编号
|
||||||
CommodityName string `json:"commodity_name"` // 商品名称
|
CommodityName string `json:"commodity_name"` // 商品名称
|
||||||
ErpCategoryId uint32 `json:"erp_category_id"` // 商品分类
|
ErpCategoryId uint32 `json:"erp_category_id"` // 商品分类
|
||||||
|
IsIMEI uint32 `json:"is_imei"` // 是否串码:0-查全部 1-查串码类 2-查非串码
|
||||||
StockType uint32 `json:"stock_type"` // 库存情况:1-全部 2-有库存 3-无库存
|
StockType uint32 `json:"stock_type"` // 库存情况:1-全部 2-有库存 3-无库存
|
||||||
StoreId uint32 `json:"store_id"` // 门店编号
|
StoreId uint32 `json:"store_id"` // 门店编号
|
||||||
PageIndex int `json:"pageIndex"` // 页码
|
PageIndex int `json:"pageIndex"` // 页码
|
||||||
|
@ -1944,11 +1998,11 @@ func (m *ErpStockListReq) stockNoEmptyList(c *gin.Context) (*ErpStockListResp, e
|
||||||
} else {
|
} else {
|
||||||
if len(storeList) > 0 {
|
if len(storeList) > 0 {
|
||||||
if len(storeList) == 1 {
|
if len(storeList) == 1 {
|
||||||
qs = qs.Where("store_id = ?", storeList[0])
|
qs = qs.Where("erp_stock.store_id = ?", storeList[0])
|
||||||
es = es.Where("store_id = ?", storeList[0])
|
es = es.Where("erp_stock.store_id = ?", storeList[0])
|
||||||
} else {
|
} else {
|
||||||
qs = qs.Where("store_id IN (?)", storeList)
|
qs = qs.Where("erp_stock.store_id IN (?)", storeList)
|
||||||
es = es.Where("store_id IN (?)", storeList)
|
es = es.Where("erp_stock.store_id IN (?)", storeList)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.New("用户未绑定门店")
|
return nil, errors.New("用户未绑定门店")
|
||||||
|
@ -2011,6 +2065,14 @@ func (m *ErpStockListReq) stockNoEmptyList(c *gin.Context) (*ErpStockListResp, e
|
||||||
es = es.Where("erp_commodity.erp_category_id=?", m.ErpCategoryId)
|
es = es.Where("erp_commodity.erp_category_id=?", m.ErpCategoryId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.IsIMEI != 0 {
|
||||||
|
if m.IsIMEI == 1 { // 查串码数据
|
||||||
|
qs = qs.Where("erp_commodity.imei_type != ?", NoIMEICommodity)
|
||||||
|
} else if m.IsIMEI == 2 { // 查非串码数据
|
||||||
|
qs = qs.Where("erp_commodity.imei_type = ?", NoIMEICommodity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var commodities []struct {
|
var commodities []struct {
|
||||||
ErpCommodity
|
ErpCommodity
|
||||||
TotalCount int
|
TotalCount int
|
||||||
|
@ -2365,11 +2427,18 @@ func (m *ErpStockCommodityListReq) GetDetailList(c *gin.Context, nType uint32) (
|
||||||
if m.IsExport == 1 {
|
if m.IsExport == 1 {
|
||||||
err := qs.Find(&commodities).Order("stock_time DESC,id DESC").Error
|
err := qs.Find(&commodities).Order("stock_time DESC,id DESC").Error
|
||||||
if err != nil && !errors.Is(err, RecordNotFound) {
|
if err != nil && !errors.Is(err, RecordNotFound) {
|
||||||
//logger.Error("dailys err:", err)
|
logger.Error("find err:", logger.Field("err", err))
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
ErpStockCommodityListSetAge(commodities)
|
ErpStockCommodityListSetAge(commodities)
|
||||||
listExport, err := InventoryDetailListExport(commodities)
|
// 判断是否有入库采购价、入库员工成本价的权限
|
||||||
|
purchasePriceFlag, _ := checkRoleMenu(c, PurchasePrice)
|
||||||
|
employeeCostPriceFlag, _ := checkRoleMenu(c, EmployeeCostPrice)
|
||||||
|
fmt.Println("purchasePriceFlag is:", purchasePriceFlag)
|
||||||
|
fmt.Println("employeeCostPriceFlag is:", employeeCostPriceFlag)
|
||||||
|
logger.Info("purchasePriceFlag is:", logger.Field("purchasePriceFlag", purchasePriceFlag))
|
||||||
|
logger.Info("employeeCostPriceFlag is:", logger.Field("employeeCostPriceFlag", purchasePriceFlag))
|
||||||
|
listExport, err := InventoryDetailListExport(commodities, purchasePriceFlag, employeeCostPriceFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//logger.Error("list export err:", err)
|
//logger.Error("list export err:", err)
|
||||||
}
|
}
|
||||||
|
@ -2776,7 +2845,7 @@ func CheckAndConvertBarcode(input string) (string, error) {
|
||||||
// 4.判断逗号隔开的数据数据库是否已存在
|
// 4.判断逗号隔开的数据数据库是否已存在
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
// 检查生成的条码是否已存在
|
// 检查生成的条码是否已存在
|
||||||
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET(%s, erp_barcode) > 0", part))
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET('%s', erp_barcode) > 0", part))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("exist sn err")
|
logger.Error("exist sn err")
|
||||||
}
|
}
|
||||||
|
@ -2811,7 +2880,7 @@ func CheckBarcodeById(input string, commodityId uint32) (string, error) {
|
||||||
// 4.判断逗号隔开的数据数据库是否已存在
|
// 4.判断逗号隔开的数据数据库是否已存在
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
// 检查生成的条码是否已存在
|
// 检查生成的条码是否已存在
|
||||||
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET(%s, erp_barcode) > 0", part))
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET('%s', erp_barcode) > 0", part))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("exist sn err")
|
logger.Error("exist sn err")
|
||||||
}
|
}
|
||||||
|
@ -2859,7 +2928,7 @@ func GenerateBarcode(categoryCode uint32) (string, error) {
|
||||||
barcode := fmt.Sprintf("%03s%s%s", category.Number[:3], dateCode, randomNumber)
|
barcode := fmt.Sprintf("%03s%s%s", category.Number[:3], dateCode, randomNumber)
|
||||||
|
|
||||||
// 检查生成的条码是否已存在
|
// 检查生成的条码是否已存在
|
||||||
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET(%s, erp_barcode) > 0", barcode))
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET('%s', erp_barcode) > 0", barcode))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("exist sn err")
|
logger.Error("exist sn err")
|
||||||
}
|
}
|
||||||
|
|
|
@ -3913,6 +3913,7 @@ func queryRetailDetailCommon(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp
|
||||||
}
|
}
|
||||||
if req.CashierId != 0 { // 支付方式
|
if req.CashierId != 0 { // 支付方式
|
||||||
qs = qs.Where("JSON_CONTAINS(cashier_list, ?)", fmt.Sprintf(`{"cashier_id":%d}`, req.CashierId))
|
qs = qs.Where("JSON_CONTAINS(cashier_list, ?)", fmt.Sprintf(`{"cashier_id":%d}`, req.CashierId))
|
||||||
|
qs = qs.Where("retail_type=?", RetailTypeSale)
|
||||||
//totalPerQs = totalPerQs.Where("erp_order_pay_way.cashier_id = ?", req.CashierId)
|
//totalPerQs = totalPerQs.Where("erp_order_pay_way.cashier_id = ?", req.CashierId)
|
||||||
}
|
}
|
||||||
if req.StartTime != "" { // 审核开始时间
|
if req.StartTime != "" { // 审核开始时间
|
||||||
|
|
|
@ -1508,7 +1508,7 @@ func checkPurchaseInventory(req *ErpPurchaseInventoryReq, imeiCheckFlag bool) er
|
||||||
|
|
||||||
// 如果该商品是串码商品,判断其串码是否会重复
|
// 如果该商品是串码商品,判断其串码是否会重复
|
||||||
if inventory.IMEI != "" {
|
if inventory.IMEI != "" {
|
||||||
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET(%s, imei) > 0", inventory.IMEI))
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET('%s', imei) > 0", inventory.IMEI))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("exist sn err")
|
logger.Error("exist sn err")
|
||||||
}
|
}
|
||||||
|
@ -3865,6 +3865,7 @@ func getReportByOrderFromCommon(req *ErpPurchaseReportByOrderReq, c *gin.Context
|
||||||
resp.List = reportByOrderDataList
|
resp.List = reportByOrderDataList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nTotalAmount = math.Round(nTotalAmount*100) / 100
|
||||||
resp.Amount = nTotalAmount
|
resp.Amount = nTotalAmount
|
||||||
resp.Count = nTotalCount
|
resp.Count = nTotalCount
|
||||||
//resp.Total = int(count)
|
//resp.Total = int(count)
|
||||||
|
@ -5764,6 +5765,12 @@ func GetReportDetail(req *ErpPurchaseReportDetailReq, c *gin.Context) (*ErpPurch
|
||||||
resp.Total = int(count)
|
resp.Total = int(count)
|
||||||
resp.Price, resp.EmployeePrice, resp.RejectPrice, resp.DifferencePrice = calculatePrices(reportList)
|
resp.Price, resp.EmployeePrice, resp.RejectPrice, resp.DifferencePrice = calculatePrices(reportList)
|
||||||
|
|
||||||
|
// 四舍五入保留2位小数
|
||||||
|
resp.Price = math.Round(resp.Price*100) / 100
|
||||||
|
resp.EmployeePrice = math.Round(resp.EmployeePrice*100) / 100
|
||||||
|
resp.RejectPrice = math.Round(resp.RejectPrice*100) / 100
|
||||||
|
resp.DifferencePrice = math.Round(resp.DifferencePrice*100) / 100
|
||||||
|
|
||||||
if req.IsExport == 1 {
|
if req.IsExport == 1 {
|
||||||
resp.List = reportList
|
resp.List = reportList
|
||||||
filePath, err := reportDetailExport(resp)
|
filePath, err := reportDetailExport(resp)
|
||||||
|
|
|
@ -9441,7 +9441,7 @@ const docTemplate = `{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"bank_trx_no": {
|
"bank_trx_no": {
|
||||||
"description": "银行流水号",
|
"description": "银联流水号",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"bill_sn": {
|
"bill_sn": {
|
||||||
|
@ -11249,6 +11249,10 @@ const docTemplate = `{
|
||||||
"description": "商品分类",
|
"description": "商品分类",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"is_imei": {
|
||||||
|
"description": "是否串码:0-查全部 1-查串码类 2-查非串码",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"pageIndex": {
|
"pageIndex": {
|
||||||
"description": "页码",
|
"description": "页码",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
|
|
|
@ -9430,7 +9430,7 @@
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"bank_trx_no": {
|
"bank_trx_no": {
|
||||||
"description": "银行流水号",
|
"description": "银联流水号",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"bill_sn": {
|
"bill_sn": {
|
||||||
|
@ -11238,6 +11238,10 @@
|
||||||
"description": "商品分类",
|
"description": "商品分类",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"is_imei": {
|
||||||
|
"description": "是否串码:0-查全部 1-查串码类 2-查非串码",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"pageIndex": {
|
"pageIndex": {
|
||||||
"description": "页码",
|
"description": "页码",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
|
|
|
@ -2413,7 +2413,7 @@ definitions:
|
||||||
models.ErpOrderRetailDetailReq:
|
models.ErpOrderRetailDetailReq:
|
||||||
properties:
|
properties:
|
||||||
bank_trx_no:
|
bank_trx_no:
|
||||||
description: 银行流水号
|
description: 银联流水号
|
||||||
type: string
|
type: string
|
||||||
bill_sn:
|
bill_sn:
|
||||||
description: 单据编号
|
description: 单据编号
|
||||||
|
@ -3730,6 +3730,9 @@ definitions:
|
||||||
erp_category_id:
|
erp_category_id:
|
||||||
description: 商品分类
|
description: 商品分类
|
||||||
type: integer
|
type: integer
|
||||||
|
is_imei:
|
||||||
|
description: 是否串码:0-查全部 1-查串码类 2-查非串码
|
||||||
|
type: integer
|
||||||
pageIndex:
|
pageIndex:
|
||||||
description: 页码
|
description: 页码
|
||||||
type: integer
|
type: integer
|
||||||
|
|
Loading…
Reference in New Issue
Block a user