Files
jx-callback/business/model/dao/report.go
2020-03-10 13:53:11 +08:00

361 lines
13 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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"`
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 []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(desired_fee) 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(pm_subsidy_money) pm_subsidy_money,
SUM(earning_price) earning_price,
SUM(total_shop_money-earning_price-desired_fee-distance_freight_money-waybill_tip_money-80) total_gross_profit
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
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 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)
Begin(db)
defer Commit(db)
if err = GetRows(db, &priceReferSnapshot, sql, sqlParams...); err == nil {
totalCount = GetLastTotalRowCount(db)
}
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...)
}