410 lines
16 KiB
Go
410 lines
16 KiB
Go
package dao
|
||
|
||
import (
|
||
"time"
|
||
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
)
|
||
|
||
type StatisticsForOrdersExists struct {
|
||
StoreID int `orm:"column(store_id)" json:"storeId"`
|
||
}
|
||
|
||
type StatisticsReportForOrdersList struct {
|
||
StatisticsForOrdersExists
|
||
StoreName string `json:"name"` //门店名
|
||
OrderCounts int `json:"orderCounts"` //订单数
|
||
SalePrice int `json:"salePrice"` //GMV(售卖价)
|
||
ActualPayPrice int `json:"actualPayPrice"` //实付
|
||
ShopPrice int `json:"shopPrice"` //京西
|
||
DiscountMoney int `json:"discountMoney"` //优惠
|
||
DesiredFee int `json:"desiredFee"` //配送费
|
||
DistanceFreightMoney int `json:"distanceFreightMoney"` //远距离
|
||
WaybillTipMoney int `json:"waybillTipMoney"` //小费
|
||
TotalShopMoney int `json:"totalShopMoney"` //平台结算
|
||
PmSubsidyMoney int `json:"pmSubsidyMoney"` //平台补贴
|
||
EarningPrice int `json:"earningPrice"` //门店收益(预计收益)
|
||
TotalGrossProfit int `json:"totalGrossProfit"` //总毛利
|
||
ComGrossProfit float32 `json:"comGrossProfit"` //公司毛利
|
||
CityManagerGrossProfit float32 `json:"cityManagerGrossProfit"` //城市经理毛利
|
||
MarketManName string `json:"marketManName"` //市场负责人
|
||
OperatorName string `json:"operatorName"` //运营负责人
|
||
OperatorName2 string `json:"operatorName2"`
|
||
OperatorName3 string `json:"operatorName3"`
|
||
|
||
Address string `json:"address"`
|
||
CityName string `json:"cityName"`
|
||
Status int `json:"status"`
|
||
Tel1 string `orm:"size(32);index" json:"tel1"`
|
||
}
|
||
|
||
type PriceReferSnapshotExt struct {
|
||
model.PriceReferSnapshot
|
||
CityName string `json:"cityName"`
|
||
SkuName string `json:"skuName"`
|
||
SpecQuality float32
|
||
Unit string
|
||
SpecUnit string
|
||
}
|
||
|
||
//查询统计订单信息
|
||
func GetStatisticsReportForOrders(db *DaoDB, storeIDs, vendorIDs []int, fromDate time.Time, toDate time.Time, marketPhone, jdPhone, mtPhone, ebaiPhone string) (statisticsReportForOrdersList []*StatisticsReportForOrdersList, err error) {
|
||
sql := `
|
||
SELECT
|
||
c.id store_id,
|
||
c.name store_name,
|
||
c.address,
|
||
s.order_counts,
|
||
s.sale_price,
|
||
s.actual_pay_price,
|
||
s.shop_price,
|
||
s.discount_money,
|
||
s.desired_fee,
|
||
s.distance_freight_money,
|
||
s.waybill_tip_money,
|
||
s.total_shop_money,
|
||
s.pm_subsidy_money,
|
||
s.earning_price,
|
||
s.total_gross_profit,
|
||
IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,s.total_gross_profit,(s.total_gross_profit*c.jx_brand_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) com_gross_profit,
|
||
IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,0,(s.total_gross_profit*c.market_add_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) city_manager_gross_profit,
|
||
c.status, c.tel1,
|
||
IF(mm.name <> '', mm.name, mm.user_id2) market_man_name,
|
||
IF(om.name <> '', om.name, om.user_id2) operator_name,
|
||
IF(om2.name <> '', om2.name, om2.user_id2) operator_name2,
|
||
IF(om3.name <> '', om3.name, om3.user_id2) operator_name3,
|
||
p.name city_name
|
||
FROM store c
|
||
LEFT JOIN place p ON p.code = c.city_code
|
||
LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = c.market_man_phone
|
||
LEFT JOIN user om ON om.mobile <> '' AND om.mobile = c.operator_phone
|
||
LEFT JOIN user om2 ON om2.mobile <> '' AND om2.mobile = c.operator_phone2
|
||
LEFT JOIN user om3 ON om3.mobile <> '' AND om3.mobile = c.operator_phone3
|
||
JOIN
|
||
(
|
||
SELECT ss.*,
|
||
ss.earning_price1 - IFNULL(ss.afs_shop_price,0) earning_price,
|
||
ss.total_shop_money1 - IFNULL(ss.afs_total_money,0) total_shop_money,
|
||
ss.total_gross_profit1 + IFNULL(ss.afs_shop_price,0) - IFNULL(ss.afs_total_money,0) - ss.order_counts*0.8*100 total_gross_profit
|
||
FROM (
|
||
SELECT
|
||
IF(a.jx_store_id <> 0,a.jx_store_id,a.store_id) store_id,
|
||
COUNT(*) order_counts,
|
||
SUM(a.sale_price) sale_price,
|
||
SUM(a.actual_pay_price) actual_pay_price,
|
||
SUM(a.shop_price) shop_price,
|
||
SUM(a.discount_money) discount_money,
|
||
SUM(b.desired_fee) desired_fee,
|
||
SUM(a.distance_freight_money) distance_freight_money,
|
||
SUM(IF(a.vendor_id = a.waybill_vendor_id,a.waybill_tip_money,0)) waybill_tip_money,
|
||
SUM(a.total_shop_money) total_shop_money1,
|
||
SUM(a.pm_subsidy_money) pm_subsidy_money,
|
||
SUM(IF(a.earning_type = 1, a.earning_price, a.new_earning_price)) earning_price1,
|
||
SUM(a.total_shop_money-IF(a.earning_type = 1, a.earning_price, a.new_earning_price)-b.desired_fee) total_gross_profit1,
|
||
SUM(d.shop_price) afs_shop_price,
|
||
SUM(IF(d.refund_money_by_cal > 0, d.refund_money_by_cal, 0)) afs_total_money
|
||
FROM goods_order a
|
||
LEFT JOIN waybill b ON IF(a.waybill_vendor_id = -1,a.vendor_order_id,a.vendor_waybill_id) = b.vendor_waybill_id
|
||
LEFT JOIN afs_order c ON c.vendor_order_id = a.vendor_order_id
|
||
LEFT JOIN order_sku_financial d ON d.afs_order_id = c.afs_order_id AND d.is_afs_order = ?
|
||
WHERE a.status = ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
model.YES,
|
||
model.OrderStatusFinished,
|
||
}
|
||
if !utils.IsTimeZero(fromDate) && !utils.IsTimeZero(toDate) {
|
||
sql += ` AND a.order_created_at BETWEEN ? AND ?`
|
||
sqlParams = append(sqlParams, fromDate, toDate)
|
||
}
|
||
if len(storeIDs) > 0 {
|
||
sql += ` AND IF(a.jx_store_id != 0, a.jx_store_id, a.store_id) IN(` + GenQuestionMarks(len(storeIDs)) + `)`
|
||
sqlParams = append(sqlParams, storeIDs)
|
||
}
|
||
if len(vendorIDs) > 0 {
|
||
sql += ` AND a.vendor_id IN(` + GenQuestionMarks(len(vendorIDs)) + `)`
|
||
sqlParams = append(sqlParams, vendorIDs)
|
||
}
|
||
sql += `
|
||
GROUP BY 1
|
||
)ss ) s
|
||
ON s.store_id = c.id
|
||
WHERE 1 = 1
|
||
`
|
||
if len(storeIDs) > 0 {
|
||
sql += ` AND c.id IN (` + GenQuestionMarks(len(storeIDs)) + `)`
|
||
sqlParams = append(sqlParams, storeIDs)
|
||
}
|
||
if marketPhone != "" {
|
||
sql += ` AND c.market_man_phone = ?`
|
||
sqlParams = append(sqlParams, marketPhone)
|
||
}
|
||
if jdPhone != "" {
|
||
sql += ` AND c.operator_phone = ?`
|
||
sqlParams = append(sqlParams, jdPhone)
|
||
}
|
||
if mtPhone != "" {
|
||
sql += ` AND c.operator_phone2 = ?`
|
||
sqlParams = append(sqlParams, mtPhone)
|
||
}
|
||
if ebaiPhone != "" {
|
||
sql += ` AND c.operator_phone3 = ?`
|
||
sqlParams = append(sqlParams, ebaiPhone)
|
||
}
|
||
if err = GetRows(db, &statisticsReportForOrdersList, sql, sqlParams...); err == nil {
|
||
return statisticsReportForOrdersList, nil
|
||
}
|
||
return nil, err
|
||
}
|
||
|
||
//查询统计售后单信息
|
||
func GetGetStatisticsReportForAfsOrders(db *DaoDB, storeIDs []int, fromDate time.Time, toDate time.Time) (statisticsReportForOrdersList []*StatisticsReportForOrdersList, err error) {
|
||
sql := `
|
||
SELECT
|
||
c.id store_id,
|
||
c.name store_name,
|
||
s.order_counts,
|
||
s.sale_price,
|
||
s.actual_pay_price,
|
||
s.shop_price,
|
||
s.discount_money,
|
||
s.desired_fee,
|
||
s.distance_freight_money,
|
||
s.waybill_tip_money,
|
||
s.total_shop_money,
|
||
s.pm_subsidy_money,
|
||
s.earning_price,
|
||
s.total_gross_profit,
|
||
IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,total_gross_profit,(total_gross_profit*c.jx_brand_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) com_gross_profit,
|
||
IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,0,(total_gross_profit*c.market_add_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) city_manager_gross_profit,
|
||
c.status, c.tel1,
|
||
IF(mm.name <> '', mm.name, mm.user_id2) market_man_name,
|
||
IF(om.name <> '', om.name, om.user_id2) operator_name,
|
||
IF(om2.name <> '', om2.name, om2.user_id2) operator_name2,
|
||
IF(om3.name <> '', om3.name, om3.user_id2) operator_name3,
|
||
p.name city_name
|
||
FROM store c
|
||
LEFT JOIN place p ON p.code = c.city_code
|
||
LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = c.market_man_phone
|
||
LEFT JOIN user om ON om.mobile <> '' AND om.mobile = c.operator_phone
|
||
LEFT JOIN user om2 ON om2.mobile <> '' AND om2.mobile = c.operator_phone2
|
||
LEFT JOIN user om3 ON om3.mobile <> '' AND om3.mobile = c.operator_phone3
|
||
LEFT JOIN
|
||
(
|
||
SELECT
|
||
IF(a.jx_store_id <> 0,a.jx_store_id,store_id) store_id,
|
||
COUNT(*) order_counts,
|
||
SUM(sale_price) sale_price,
|
||
SUM(actual_pay_price) actual_pay_price,
|
||
SUM(shop_price) shop_price,
|
||
SUM(discount_money) discount_money,
|
||
SUM(afs_freight_money) desired_fee,
|
||
SUM(distance_freight_money) distance_freight_money,
|
||
SUM(IF(a.vendor_id = a.waybill_vendor_id,waybill_tip_money,0)) waybill_tip_money,
|
||
SUM(total_shop_money) total_shop_money,
|
||
SUM(b.pm_subsidy_money) pm_subsidy_money,
|
||
SUM(earning_price) earning_price,
|
||
SUM(total_shop_money-earning_price-afs_freight_money-distance_freight_money-waybill_tip_money-80) total_gross_profit
|
||
FROM goods_order a JOIN afs_order b ON a.vendor_order_id = b.vendor_order_id
|
||
WHERE a.status != ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
model.OrderStatusCanceled, //排除已取消的订单
|
||
}
|
||
if !utils.IsTimeZero(fromDate) && !utils.IsTimeZero(toDate) {
|
||
sql += ` AND a.order_created_at BETWEEN ? AND ?`
|
||
sqlParams = append(sqlParams, fromDate, toDate)
|
||
}
|
||
if len(storeIDs) > 0 {
|
||
sql += ` AND IF(a.jx_store_id != 0, a.jx_store_id, a.store_id) IN(` + GenQuestionMarks(len(storeIDs)) + `)`
|
||
sqlParams = append(sqlParams, storeIDs)
|
||
}
|
||
sql += `
|
||
GROUP BY 1
|
||
)s
|
||
ON s.store_id = c.id
|
||
`
|
||
if len(storeIDs) > 0 {
|
||
sql += ` WHERE c.id IN (` + GenQuestionMarks(len(storeIDs)) + `)`
|
||
sqlParams = append(sqlParams, storeIDs)
|
||
}
|
||
if err = GetRows(db, &statisticsReportForOrdersList, sql, sqlParams...); err == nil {
|
||
return statisticsReportForOrdersList, nil
|
||
}
|
||
return nil, err
|
||
}
|
||
|
||
func GetStatisticsReportForStoreSkusPrice(db *DaoDB, cityCodes, skuIDs []int) (priceReferSnapshot []*model.PriceReferSnapshot, err error) {
|
||
var sql string
|
||
sql1 := `
|
||
SELECT a.sku_id, c.name_id,
|
||
`
|
||
sql2 := `
|
||
MAX(a.jd_price) max_jd_price,
|
||
MIN(a.jd_price) min_jd_price,
|
||
ROUND(AVG(a.jd_price)) avg_jd_price,
|
||
ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.jd_price ORDER BY a.jd_price),',',Count(1)/2),',',-1),2) mid_jd_price,
|
||
MAX(a.ebai_price) max_ebai_price,
|
||
MIN(a.ebai_price) min_ebai_price,
|
||
ROUND(AVG(a.ebai_price)) avg_ebai_price,
|
||
ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.ebai_price ORDER BY a.ebai_price),',',Count(1)/2),',',-1),2) mid_ebai_price,
|
||
MAX(a.mtwm_price) max_mtwm_price,
|
||
MIN(a.mtwm_price) min_mtwm_price,
|
||
ROUND(AVG(a.mtwm_price)) avg_mtwm_price,
|
||
ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.mtwm_price ORDER BY a.mtwm_price),',',Count(1)/2),',',-1),2) mid_mtwm_price,
|
||
t1.max_sale_price,
|
||
t1.min_sale_price,
|
||
t1.avg_sale_price,
|
||
t1.max_vendor_price,
|
||
t1.min_vendor_price,
|
||
t1.avg_vendor_price
|
||
FROM store_sku_bind a
|
||
JOIN store b ON a.store_id = b.id AND b.deleted_at = ? AND b.status != ?
|
||
JOIN sku c ON a.sku_id = c.id
|
||
LEFT JOIN (
|
||
SELECT SUM(t1.count),t1.sku_id,MAX(t1.sale_price) max_sale_price,MIN(t1.sale_price) min_sale_price,ROUND(AVG(t1.sale_price)) avg_sale_price,MAX(t1.vendor_price) max_vendor_price,MIN(t1.vendor_price) min_vendor_price,ROUND(AVG(t1.vendor_price)) avg_vendor_price
|
||
FROM order_sku t1
|
||
WHERE t1.order_created_at BETWEEN ? AND NOW()
|
||
GROUP BY 2
|
||
)t1 ON t1.sku_id = a.sku_id
|
||
WHERE a.deleted_at = ?
|
||
`
|
||
sql = sql1 + "b.city_code, " + sql2
|
||
sqlParams := []interface{}{
|
||
utils.DefaultTimeValue,
|
||
model.StoreStatusDisabled,
|
||
time.Now().AddDate(0, -1, 0),
|
||
utils.DefaultTimeValue,
|
||
}
|
||
if len(skuIDs) > 0 {
|
||
sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||
sqlParams = append(sqlParams, skuIDs)
|
||
}
|
||
if len(cityCodes) > 0 {
|
||
sql += " AND b.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")"
|
||
sqlParams = append(sqlParams, cityCodes)
|
||
}
|
||
sql += ` GROUP BY 1,2,3
|
||
UNION `
|
||
sql += sql1 + "0 city_code," + sql2
|
||
if len(skuIDs) > 0 {
|
||
sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||
sqlParams = append(sqlParams, skuIDs)
|
||
}
|
||
if len(cityCodes) > 0 {
|
||
sql += " AND b.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")"
|
||
sqlParams = append(sqlParams, cityCodes)
|
||
}
|
||
sql += " GROUP BY 1,2"
|
||
sqlParams = append(sqlParams, sqlParams...)
|
||
if err = GetRows(db, &priceReferSnapshot, sql, sqlParams...); err == nil {
|
||
return priceReferSnapshot, nil
|
||
}
|
||
return nil, err
|
||
}
|
||
|
||
func GetPriceReferSnapshot(db *DaoDB, cityCodes, skuIDs []int, skuNameID int, snapDate time.Time, offset, pageSize int) (priceReferSnapshot []*PriceReferSnapshotExt, totalCount int, err error) {
|
||
sql := `
|
||
SELECT SQL_CALC_FOUND_ROWS a.*,IF(a.city_code = 0,'全国',b.name) city_name
|
||
FROM price_refer_snapshot a
|
||
LEFT JOIN place b ON a.city_code = b.code
|
||
WHERE 1=1
|
||
AND a.deleted_at = ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
utils.DefaultTimeValue,
|
||
}
|
||
if skuNameID > 0 {
|
||
sql += " AND a.name_id = ?"
|
||
sqlParams = append(sqlParams, skuNameID)
|
||
}
|
||
if len(skuIDs) > 0 {
|
||
sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||
sqlParams = append(sqlParams, skuIDs)
|
||
}
|
||
if len(cityCodes) > 0 {
|
||
sql += " AND a.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")"
|
||
sqlParams = append(sqlParams, cityCodes)
|
||
}
|
||
if !utils.IsTimeZero(snapDate) {
|
||
sql += " AND a.snapshot_at = ?"
|
||
sqlParams = append(sqlParams, snapDate)
|
||
}
|
||
sql += " LIMIT ? OFFSET ?"
|
||
sqlParams = append(sqlParams, pageSize, offset)
|
||
txDB, _ := Begin(db)
|
||
defer Commit(db, txDB)
|
||
if err = GetRowsTx(txDB, &priceReferSnapshot, sql, sqlParams...); err == nil {
|
||
totalCount = GetLastTotalRowCount2(db, txDB)
|
||
}
|
||
for _, v := range priceReferSnapshot {
|
||
skuList, err2 := GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil)
|
||
err = err2
|
||
if len(skuList) > 0 {
|
||
skuAndName := skuList[0]
|
||
jxSkuDetailName := jxutils.ComposeSkuNameOriginal(skuAndName.Prefix, skuAndName.Name, skuAndName.Comment, skuAndName.Unit, skuAndName.SpecQuality, skuAndName.SpecUnit, 0)
|
||
v.SkuName = jxSkuDetailName
|
||
}
|
||
}
|
||
return priceReferSnapshot, totalCount, err
|
||
}
|
||
|
||
func GetPriceReferSnapshotNoPage(db *DaoDB, cityCodes, skuIDs, skuNameIDs []int, snapDate time.Time) (priceReferSnapshot []*model.PriceReferSnapshot, err error) {
|
||
sql := `
|
||
SELECT a.*
|
||
FROM price_refer_snapshot a
|
||
WHERE 1=1
|
||
AND a.deleted_at = ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
utils.DefaultTimeValue,
|
||
}
|
||
if len(skuNameIDs) > 0 {
|
||
sql += " AND a.name_id IN (" + GenQuestionMarks(len(skuNameIDs)) + ")"
|
||
sqlParams = append(sqlParams, skuNameIDs)
|
||
}
|
||
if len(skuIDs) > 0 {
|
||
sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||
sqlParams = append(sqlParams, skuIDs)
|
||
}
|
||
if len(cityCodes) > 0 {
|
||
sql += " AND a.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")"
|
||
sqlParams = append(sqlParams, cityCodes)
|
||
}
|
||
if !utils.IsTimeZero(snapDate) {
|
||
sql += " AND a.snapshot_at = ?"
|
||
sqlParams = append(sqlParams, snapDate)
|
||
}
|
||
err = GetRows(db, &priceReferSnapshot, sql, sqlParams...)
|
||
return priceReferSnapshot, err
|
||
}
|
||
|
||
func DeletePriceReferHistory(db *DaoDB, snapDate time.Time) (num int64, err error) {
|
||
sql := `
|
||
DELETE FROM price_refer_snapshot
|
||
WHERE snapshot_at <= ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
snapDate,
|
||
}
|
||
return ExecuteSQL(db, sql, sqlParams...)
|
||
}
|
||
|
||
type UserMemberReportResult struct {
|
||
Mobile string `json:"mobile"` //电话
|
||
Name string `json:"name"` //姓名
|
||
Status int `json:"status"` //状态
|
||
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||
BuyCount int `json:"buyCount"` //购买次数
|
||
NewPrice int64 `json:"newPrice"` //最近订单金额
|
||
FinishedCount int `json:"finishedCount"` //完成订单数
|
||
BuyPrice int `json:"buyPrice"` //购买总金额
|
||
FinishedPrice int `json:"finishedPrice"` //完成订单金额
|
||
GoodsCommentCount int `json:"goodsCommentCount"` //好评数
|
||
BadCommentCount int `json:"badCommentCount"` //差评数
|
||
CityCode int `json:"cityCode"` // 常住城市
|
||
CityName string `json:"cityName"`
|
||
}
|