Commit 08d66024 by lizefeng

新增库存分计算任务

parent 8eee12ed
......@@ -73,8 +73,9 @@ namespace AutoTurnOver.DB
{
var dbSku = new t_base_shopify_refund
{
bailun_order_id = item.bailun_order_id,
bailun_sku = item.bailun_sku,
bailun_order_id = item.bailun_order_id,
warehouse_code = item.warehouse_code,
bailun_sku = item.bailun_sku,
order_pay_time = item.order_pay_time,
origin_order_id = item.origin_order_id,
refund_amount = item.refund_amount,
......@@ -91,17 +92,29 @@ namespace AutoTurnOver.DB
}
}
public static void CalculationStockScore(string sku=null)
{
var skus = _connection.Query<dc_report_invest_return_sku>(" select * from dc_report_invest_return_sku ").ToList() ;
if (!string.IsNullOrWhiteSpace(sku))
{
skus = skus.Where(s => s.sku == sku).ToList();
}
foreach (var skuItem in skus)
{
CalculationStockScoreSingle(skuItem);
}
}
/// <summary>
/// 计算仓库分数
/// </summary>
/// <param name="sku"></param>
public static void CalculationStockScore(dc_report_invest_return_sku sku)
public static void CalculationStockScoreSingle(dc_report_invest_return_sku sku)
{
var day30Btime = DateTime.Now.AddDays(-31).ToDayHome();
var day7Btime = DateTime.Now.AddDays(-31).ToDayHome();
var dayEtime = DateTime.Now.AddDays(-1).ToDayEnd();
// 查询这个sku涉及的所有仓库
var stocks = _connection.Query<dc_base_stock>(" select * from dc_base_stock where sku=@sku ", new { sku = sku.sku });
var stocks = _connection.Query<dc_base_stock>(" select * from dc_base_stock where bailun_sku=@sku ", new { sku = sku.sku });
// 查询sku 基础表
var baseSku = _connection.QueryFirstOrDefault<dc_base_sku>(" select * from dc_base_sku where bailun_sku=@bailun_sku ", new
{
......@@ -118,7 +131,7 @@ namespace AutoTurnOver.DB
{
warehouse_code = stockItem.warehouse_code,
bailun_sku = sku.sku
});
})??new dc_mid_transit { };
// 查询历史订单
var orders = _connection.Query<dc_base_oms_sku>(" select * from dc_base_oms_sku where warehouse_code=@warehouse_code and bailun_sku=@bailun_sku and bailun_order_status not in ('Canceled') and bailun_interception_status in ('None', 'Failed') and platform_type != 'FBA' and paid_time<=@etime ", new
{
......@@ -161,15 +174,15 @@ namespace AutoTurnOver.DB
if (orders.Any(s => s.seller_order_exchange_rate > 0))
{
ana.seller_order_exchange_rate = orders.Where(s => s.seller_order_exchange_rate > 0).Average(s => s.seller_order_exchange_rate);
// ana.seller_order_exchange_rate = orders.Where(s => s.paid_time >= day30Btime).Where(s => s.seller_order_exchange_rate > 0).Average(s => s.seller_order_exchange_rate);
}
ana.quantity_purchase_amount = ana.quantity_purchase * ana.price;
ana.quantity_purchase_amount = ana.quantity_purchase * ana.price;
ana.quantity_transfer_amount = ana.quantity_transfer * ana.price;
ana.stock_amount = ana.stock * ana.price;
ana.library_stock_amount = ana.library_stock * ana.price;
ana.sales_day_average = (ana.sales_day_30 / 30 * 0.5M) + (ana.sales_day_7 / 7 * 0.5M);
ana.vendibility_days = ana.stock / ana.sales_day_average;
ana.sales_day_average =Math.Round( (ana.sales_day_30 .Division( 30M) * 0.5M) + (ana.sales_day_7.Division( 7M) * 0.5M),0);
ana.vendibility_days = Math.Round( ana.stock.Division( ana.sales_day_average),0);
/// 30天利润
///预计30天内销量,可售天数大于30天的,则为加权日均销量*30,可售天数小于30天的,则为加权日均销量* 可售天数
///预计30天内销售额=预计30天内销量* 单位售价
......@@ -186,26 +199,57 @@ namespace AutoTurnOver.DB
if (orders.Any(s => s.amount_sales > 0 && s.seller_order_exchange_rate > 0))
{
//过去30天 单位售价
ana.gmv_day30_avg_unit_price_cny = orders.Where(s => s.paid_time >= day30Btime).Where(s => s.amount_sales > 0 && s.seller_order_exchange_rate > 0).Average(s => s.amount_sales * s.seller_order_exchange_rate);
ana.gmv_day30_avg_unit_price_cny = 0;
var unit_price_orders = orders.Where(s => s.amount_sales > 0 && s.seller_order_exchange_rate > 0);
if (unit_price_orders.Count() >= 1)
{
ana.gmv_day30_avg_unit_price_cny = unit_price_orders.Average(s => s.amount_sales * s.seller_order_exchange_rate);
}
}
//预计30天内销售额
ana.gmv_day_30_forecast_cny = ana.sales_day_30_forecast * ana.gmv_day30_avg_unit_price_cny;
// 计算最近1个月的广告费率
var adFees = _connection.Query<t_base_shopify_adfee_order>(" select * from t_base_shopify_adfee_order where is_delete=0 and bailun_sku=@bailun_sku and warehouse_code=@warehouse_code and order_pay_time>=@order_pay_btime and order_pay_time<=@order_pay_etime ", new {
var adFees = _connection.Query<t_base_shopify_adfee_order>(" select * from t_base_shopify_adfee_order where is_delete=0 and bailun_sku=@bailun_sku and warehouse_code=@warehouse_code and order_pay_time>=@order_pay_btime and order_pay_time<=@order_pay_etime ", new
{
bailun_sku = ana.sku,
warehouse_code = ana.warehouse_code,
order_pay_btime = day30Btime,
order_pay_etime = dayEtime,
}).ToList();
ana.adfee_day_30 = adFees.Sum(s => s.order_fee);
ana.amount_total_day_30 = orders.Sum(s => s.amount_total * s.order_to_usd_exchange_rate);
ana.adfee_rate = Math.Round(ana.adfee_day_30 / ana.amount_total_day_30, 4);
ana.adfee_day_30 = adFees.Sum(s => s.order_fee);
ana.amount_total_day_30 = orders.Where(s => s.paid_time >= day30Btime).Sum(s => s.amount_total * s.order_to_usd_exchange_rate);
ana.adfee_rate = Math.Round(ana.adfee_day_30 .Division( ana.amount_total_day_30), 4);
// 计算最近1个月的平台费率
ana.platform_fee_day_30 = orders.Sum(s => s.cost_platform_fee * s.order_to_usd_exchange_rate);
ana.platform_fee_rate = Math.Round(ana.platform_fee_day_30 / ana.amount_total_day_30, 4);
ana.platform_fee_day_30 = orders.Where(s => s.paid_time >= day30Btime).Sum(s => s.cost_platform_fee * s.order_to_usd_exchange_rate);
ana.platform_fee_rate = Math.Round(ana.platform_fee_day_30 .Division( ana.amount_total_day_30), 4);
// 计算最近1个月的退款费率
// de的读btm的,其他的读oms的
if ("de".Equals(ana.project, StringComparison.InvariantCultureIgnoreCase))
{
// 计算最近1个月的广告费率
ana.refund_amount_day_30 = _connection.QueryFirstOrDefault<decimal?>(" select * from t_base_shopify_refund where bailun_sku=@bailun_sku and warehouse_code=@warehouse_code and order_pay_time>=@order_pay_btime and order_pay_time<=@order_pay_etime ", new
{
bailun_sku = ana.sku,
warehouse_code = ana.warehouse_code,
order_pay_btime = day30Btime,
order_pay_etime = dayEtime,
}) ?? 0M;
}
else
{
ana.refund_amount_day_30 = 0;
}
ana.refund_rate = Math.Round(ana.refund_amount_day_30 .Division( ana.amount_total_day_30), 4); ;
// 计算最近1个月的退款费率
// 预计30天利润
ana.profit_30_forecast = ana.sales_day_30 * (1 - ana.refund_rate - ana.adfee_rate - ana.platform_fee_rate);
if (orders != null && orders.Count(s => s.paid_time != null) >= 1)
{
......@@ -213,6 +257,12 @@ namespace AutoTurnOver.DB
ana.last_order_date = orders.Where(s => s.paid_time != null).Max(s => s.paid_time.Value);
}
//计算单位运费
ana.freight_unit_price = CalculationFreight(ana.sku, ana.warehouse_code, day30Btime.AddDays(-30 *5),dayEtime);
//预估运费,库存 * 单位运费
ana.estimated_freight = ana.freight_unit_price * ana.stock;
ana.stock_score = (ana.sales_day_average * 90).Division(ana.stock) * 100;
ana.id = _connection.QueryFirstOrDefault<int?>(" select id from dc_report_invest_return_analysis where sku=@sku and warehouse_code=@warehouse_code ", new
{
sku = ana.sku,
......@@ -274,8 +324,8 @@ namespace AutoTurnOver.DB
origin_order_id = itemOrder.origin_order_id,
origin_fee = feeItem.fee,
origin_fee_cny = feeItem.fee_cny,
order_fee =Math.Round( feeItem.fee * ratio,2),
order_fee_cny =Math.Round( feeItem.fee_cny * ratio,4),
order_fee = Math.Round(feeItem.fee * ratio, 2),
order_fee_cny = Math.Round(feeItem.fee_cny * ratio, 4),
};
addfee_order.unique_id = $"{addfee_order.fee_data_id}-{addfee_order.order_unique}";
useFeeCny += addfee_order.order_fee_cny;
......@@ -284,9 +334,9 @@ namespace AutoTurnOver.DB
}
// 如果分摊之后,还有小数没有分摊均匀。就把多余的全部给最大的那笔
if(feeItem.fee_cny!= useFeeCny || feeItem.fee!= useFeeUsd)
if (feeItem.fee_cny != useFeeCny || feeItem.fee != useFeeUsd)
{
var topOrder = adfee_orders.OrderByDescending(s => s.order_amount_total_usd).FirstOrDefault();
var topOrder = adfee_orders.OrderByDescending(s => s.order_amount_total_usd).FirstOrDefault();
topOrder.order_fee += (feeItem.fee - useFeeUsd);
topOrder.order_fee_cny += (feeItem.fee_cny - useFeeCny);
}
......@@ -310,20 +360,157 @@ namespace AutoTurnOver.DB
throw;
}
}
// 清理多余的数据
_connection.Execute(" update t_base_shopify_adfee_order set is_delete=1 where fee_data_id=@fee_data_id and unique_id not in @unique_ids ",new {
_connection.Execute(" update t_base_shopify_adfee_order set is_delete=1 where fee_data_id=@fee_data_id and unique_id not in @unique_ids ", new
{
fee_data_id = feeItem.data_id,
unique_ids = adfee_orders.Select(s=>s.unique_id).ToList()
unique_ids = adfee_orders.Select(s => s.unique_id).ToList()
});
}
// 标记为已分摊
_connection.Execute(" update t_base_shopify_adfee set share_time=now() where id=@id ", new { id = feeItem.id });
}
}
/// <summary>
/// 计算单位运费
/// </summary>
public static decimal CalculationFreight(string bailun_sku, string warehouse_code, DateTime btime, DateTime etime)
{
// 清理运费计算日志
_connection.Execute(" delete from dc_base_transfer_freight_new_order where main_bailun_sku=@bailun_sku and warehouse_code=@warehouse_code ", new
{
bailun_sku = bailun_sku,
warehouse_code = warehouse_code
});
// 查询这个sku 时间范围内所有的调拨单明细
var tempDatas = _connection.Query<CalculationFreightDto>($@"select t2.sku ,
t1.`code`,
t2.deliverycount,
t1.estimatedcost as 'order_estimatedcost',
t3.deliverycount as 'order_deliverycount',
t4.weight
from dc_base_transfer_info as t1
left join dc_base_transfer_info_skus as t2 on t1.dataid = t2.dataid
left join ( select dataid,sum(deliverycount) as 'deliverycount' from dc_base_transfer_info_skus GROUP BY dataid ) as t3 on t1.dataid = t3.dataid
left join dc_base_sku as t4 on t2.sku = t4.bailun_sku
where t1.isdeleted=0
and t1.isexception = 0
and t1.creationtime >=@btime and t1.creationtime <=@etime
and t1.targetwareno=@warehouse_code
and t1.estimatedcost>0
and t1.dataid in ( select dataid from dc_base_transfer_info_skus where sku=@sku)", new
{
btime = btime,
etime = etime,
warehouse_code = warehouse_code,
sku = bailun_sku
}).ToList();
if (tempDatas != null && tempDatas.Count >= 1)
{
List<dc_base_transfer_freight_new_order> orders = new List<dc_base_transfer_freight_new_order>();
foreach (var itemGroup in tempDatas.GroupBy(s => s.code))
{
//计算该订单总sku重量
var sumWeight = itemGroup.Sum(s => s.weight * s.deliverycount);
var sumSkuCount = itemGroup.Sum(s => s.deliverycount);
var sumCost = itemGroup.FirstOrDefault().order_estimatedcost;
List<dc_base_transfer_freight_new_order> groupOrders = new List<dc_base_transfer_freight_new_order>();
foreach (var item in itemGroup.AsQueryable())
{
dc_base_transfer_freight_new_order new_order = new dc_base_transfer_freight_new_order()
{
main_bailun_sku = bailun_sku,
bailun_sku = item.sku,
gmt_update_time = DateTime.Now,
sku_count = item.deliverycount,
transfer_order_id = itemGroup.Key,
sku_weight = item.weight * item.deliverycount,
warehouse_code = warehouse_code,
order_cost = item.order_estimatedcost,
order_sku_count = sumSkuCount,
order_weight = sumWeight,
sku_cost = Math.Round((item.weight * item.deliverycount).Division(sumWeight) * item.order_estimatedcost, 2)
};
groupOrders.Add(new_order);
}
var cha = (sumCost - groupOrders.Sum(s => s.sku_cost));
if (cha>0)
{
var topSkuOrder = groupOrders.OrderByDescending(s => s.order_cost).FirstOrDefault();
topSkuOrder.order_cost += cha;
}
orders.AddRange(groupOrders);
foreach (var itemOrder in orders)
{
_connection.Insert(itemOrder);
}
}
var thisOrders = orders.Where(s => s.bailun_sku == bailun_sku).ToList();
dc_base_transfer_freight_new newData = new dc_base_transfer_freight_new()
{
bailun_sku = bailun_sku,
count = thisOrders.Sum(s => s.sku_count),
freight = thisOrders.Sum(s => s.sku_cost),
update_time = DateTime.Now,
warehouse_code = warehouse_code,
id = _connection.QueryFirstOrDefault<int?>(" select id from dc_base_transfer_freight_new where bailun_sku=@bailun_sku and warehouse_code=@warehouse_code ", new { bailun_sku = bailun_sku, warehouse_code = warehouse_code }) ?? 0
};
newData.freight_unit_price = newData.freight.Division(newData.count);
if (newData.id <= 0)
{
_connection.Insert(newData);
}
else
{
_connection.Update(newData);
}
return newData.freight_unit_price;
}
else
{
// 清空运费
_connection.Execute(" delete from dc_base_transfer_freight_new where bailun_sku=@bailun_sku and warehouse_code=@warehouse_code ", new
{
bailun_sku = bailun_sku,
warehouse_code = warehouse_code,
});
return 0;
}
}
public class CalculationFreightDto
{
public string sku { get; set; }
public string code { get; set; }
/// <summary>
/// 发货数量
/// </summary>
public decimal deliverycount { get; set; }
/// <summary>
/// 调拨单总运费
/// </summary>
public decimal order_estimatedcost { get; set; }
public string order_deliverycount { get; set; }
/// <summary>
/// sku 单位重量
/// </summary>
public decimal weight { get; set; }
}
}
}
......@@ -26,6 +26,7 @@ namespace AutoTurnOver.Models.ApiDto
public class data_dto {
public string bailun_order_id { get; set; }
public string warehouse_code { get; set; }
public string origin_order_id { get; set; }
public string bailun_sku { get; set; }
public decimal refund_amount { get; set; }
......
using System;
using System.Collections.Generic;
using System.Text;
namespace AutoTurnOver.Models
{
/// <summary>
/// sku 单位调拨费计算
/// </summary>
public class dc_base_transfer_freight_new
{
public int id { get; set; }
public string bailun_sku { get; set; }
public string warehouse_code { get; set; }
/// <summary>
/// 运费单价
/// </summary>
public decimal freight_unit_price { get; set; }
/// <summary>
/// 最近30天总运费 cny
/// </summary>
public decimal freight { get; set; }
public DateTime update_time { get; set; }
public decimal count { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace AutoTurnOver.Models
{
/// <summary>
/// sku 单位 调拨费 明细
/// </summary>
public class dc_base_transfer_freight_new_order
{
public long id { get; set; }
/// <summary>
/// 仓库sku
/// </summary>
public string bailun_sku { get; set; }
public string main_bailun_sku { get; set; }
/// <summary>
/// 仓库编码
/// </summary>
public string warehouse_code { get; set; }
/// <summary>
/// 调拨单号
/// </summary>
public string transfer_order_id { get; set; }
/// <summary>
/// 调拨总单运费
/// </summary>
public decimal order_cost { get; set; }
/// <summary>
/// 调拨单总总量
/// </summary>
public decimal order_weight { get; set; }
/// <summary>
/// 调拨单总产品数量
/// </summary>
public decimal order_sku_count { get; set; }
/// <summary>
/// 该sku 在该调拨单中分摊的总运费
/// </summary>
public decimal sku_cost { get; set; }
/// <summary>
/// 该sku 在该调拨单中的总重量
/// </summary>
public decimal sku_weight { get; set; }
/// <summary>
/// sku的购买数量
/// </summary>
public decimal sku_count { get; set; }
/// <summary>
/// 数据最后更新时间
/// </summary>
public DateTime gmt_update_time { get; set; }
}
}
......@@ -75,6 +75,10 @@ namespace AutoTurnOver.Models
///预计30天营业利润=预计30天内销量* 单位售价*(1-最近1个月的款率-最近1个月的平台费率最近1个月的广告费率)-预计30天内销量* 单位采购成本
/// </summary>
public decimal profit_30_forecast { get; set; }
/// <summary>
/// 单位运费
/// </summary>
public decimal freight_unit_price { get; set; }
/// <summary>
/// 可售天数:
......@@ -103,6 +107,10 @@ namespace AutoTurnOver.Models
/// </summary>
public decimal platform_fee_day_30 { get; set; }
/// <summary>
/// 最近30天退款金额
/// </summary>
public decimal refund_amount_day_30 { get; set; }
/// <summary>
/// 最近30天的销售额(usd)
/// </summary>
public decimal amount_total_day_30 { get; set; }
......@@ -115,6 +123,10 @@ namespace AutoTurnOver.Models
/// </summary>
public decimal platform_fee_rate { get; set; }
/// <summary>
/// 退款率 (最近30天退款金额/总销售额)
/// </summary>
public decimal refund_rate { get; set; }
/// <summary>
/// 采购在途数量
/// </summary>
public decimal quantity_purchase { get; set; }
......
......@@ -11,6 +11,7 @@ namespace AutoTurnOver.Models
{
public int id { get; set; }
public string bailun_order_id { get; set; }
public string warehouse_code { get; set; }
public string origin_order_id { get; set; }
public string bailun_sku { get; set; }
public decimal refund_amount { get; set; }
......
......@@ -48,6 +48,7 @@ namespace ResetOutofstock
// report_invest_return_dao.SynchBtmAdFees();
//report_invest_return_dao.ShareAdFee();
//report_invest_return_dao.SynchBtmOrderRefund();
//report_invest_return_dao.CalculationStockScore();
}
catch (Exception ex)
{
......
......@@ -517,7 +517,7 @@ namespace ResetOutofstock
}
});
Task.Factory.StartNew(() =>
{
......@@ -528,7 +528,7 @@ namespace ResetOutofstock
{
Console.WriteLine($"开始 拉取pps sku,线程Id:{Thread.CurrentThread.ManagedThreadId}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
report_invest_return_dao.SynchPpsSku();
Console.WriteLine($"结束 拉取pps sku,线程Id:{Thread.CurrentThread.ManagedThreadId}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
Thread.Sleep(10 * 60 * 1000);
}
......@@ -566,7 +566,7 @@ namespace ResetOutofstock
}
});
Task.Factory.StartNew(() =>
{
while (true)
......@@ -576,7 +576,6 @@ namespace ResetOutofstock
{
Console.WriteLine($"开始 分摊广告费,线程Id:{Thread.CurrentThread.ManagedThreadId}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
report_invest_return_dao.ShareAdFee();
Console.WriteLine($"结束 分摊广告费,线程Id:{Thread.CurrentThread.ManagedThreadId}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
Thread.Sleep(10 * 60 * 1000);
}
......@@ -590,6 +589,28 @@ namespace ResetOutofstock
}
});
Task.Factory.StartNew(() =>
{
while (true)
{
try
{
Console.WriteLine($"开始 计算库存分,线程Id:{Thread.CurrentThread.ManagedThreadId}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
report_invest_return_dao.CalculationStockScore();
Console.WriteLine($"结束 计算库存分,线程Id:{Thread.CurrentThread.ManagedThreadId}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
Thread.Sleep(10 * 60 * 1000);
}
catch (Exception ex)
{
Console.WriteLine(" 分摊广告费:" + ex.Message);
Console.WriteLine(" 分摊广告费 :" + ex.StackTrace);
}
}
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment