Commit 5c27d403 by 泽锋 李

新增自动下首单逻辑

parent 39c85f48
...@@ -3,6 +3,7 @@ using System; ...@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Dapper; using Dapper;
using System.Linq;
namespace AutoTurnOver.DB namespace AutoTurnOver.DB
{ {
...@@ -33,14 +34,24 @@ namespace AutoTurnOver.DB ...@@ -33,14 +34,24 @@ namespace AutoTurnOver.DB
{ {
foreach (var item in input_data.detailed) foreach (var item in input_data.detailed)
{ {
if (string.IsNullOrWhiteSpace(item.bailun_sku))
{
throw new Exception("sku必填");
}
var old_data = conn.QuerySingleOrDefault<dc_auto_first_order_sku>(" select * from dc_auto_first_order_sku where bailun_sku=@bailun_sku and warehouse_code=@warehouse_code ", new { bailun_sku = item, warehouse_code = input_data.warehouse_code }); var old_data = conn.QuerySingleOrDefault<dc_auto_first_order_sku>(" select * from dc_auto_first_order_sku where bailun_sku=@bailun_sku and warehouse_code=@warehouse_code ", new { bailun_sku = item, warehouse_code = input_data.warehouse_code });
if (old_data != null) throw new Exception($" sku {item} , 仓库编码 :{ input_data.warehouse_code} 已存在 "); if (old_data != null) throw new Exception($" sku {item} , 仓库编码 :{ input_data.warehouse_code} 已存在 ");
conn.Insert(new dc_auto_first_order_sku conn.Insert(new dc_auto_first_order_sku
{ {
bailun_sku = item, bailun_sku = item.bailun_sku,
push_date = now, push_date = now,
warehouse_code = input_data.warehouse_code, warehouse_code = input_data.warehouse_code,
sendtype = input_data.sendtype sendtype = input_data.sendtype,
brand = item.brand,
product_inner_code = item.product_inner_code,
product_sales = item.product_sales,
source = item.source,
order_time = new DateTime(1991, 1, 1)
}, t); }, t);
} }
...@@ -49,5 +60,200 @@ namespace AutoTurnOver.DB ...@@ -49,5 +60,200 @@ namespace AutoTurnOver.DB
} }
} }
/// <summary>
/// 生成采购建议
/// </summary>
public static void GeneratePurchaseAdvise()
{
using (var conn = _connection)
{
conn.Open();
using (var t = conn.BeginTransaction())
{
// 查询当前待出建议的sku
var sku_list = conn.Query<dc_auto_first_order_sku>(" select * from dc_auto_first_order_sku where order_time > '2020-01-01' ").AsList();
var rule_list = conn.Query<dc_auto_first_order_rule>(" select * from dc_auto_first_order_rule ").AsList();
var warehouse_list = conn.Query<dc_base_warehouse>(" select * from dc_base_warehouse ").AsList();
var err_count = false;
foreach (var itemGroup in sku_list.GroupBy(s => new { s.product_inner_code, s.warehouse_code }))
{
try
{
var item_warehouse = warehouse_list.FirstOrDefault(s => itemGroup.Key.warehouse_code.Equals(s.warehouse_code, StringComparison.CurrentCultureIgnoreCase));
if (item_warehouse == null)
{
throw new Exception("仓库编码不存在");
}
// 匹配规则
var item_rule = rule_list.FirstOrDefault(s => s.source == itemGroup.Max(v => v.source)
&& s.warehouse_type.Equals(item_warehouse.hq_type, StringComparison.CurrentCultureIgnoreCase)
&& (s.brand == "0" || s.brand.Equals(itemGroup.Max(v => v.brand), StringComparison.CurrentCultureIgnoreCase))
&& s.source == itemGroup.Max(v => v.source)
);
if (item_rule == null)
{
throw new Exception("未命中规则");
}
List<auto_first_order_detailed_dto> data_detailed_list = new List<auto_first_order_detailed_dto>();
if (item_rule.lower_limit_sku_count > 0 && itemGroup.Count() < item_rule.lower_limit_sku_count)
{
throw new Exception($" sku数量不超过 {item_rule.lower_limit_sku_count} 个 ");
}
if (item_rule.lower_limit_sales > 0 && itemGroup.Max(v => v.product_sales) < item_rule.lower_limit_sales)
{
throw new Exception($" 商品日均不超过 {item_rule.lower_limit_sales} 个 ");
}
// 固定数量
if (item_rule.order_type == 1)
{
var single_sku_count = item_rule.quantity;
foreach (var item in itemGroup.AsEnumerable())
{
data_detailed_list.Add(new auto_first_order_detailed_dto
{
bailun_sku = item.bailun_sku,
quantity = single_sku_count
});
}
// 自动凑moq
if (item_rule.has_collect)
{
//查询商品moq
var moq = conn.QuerySingleOrDefault<int?>(" select max('moq') from dc_base_sku where product_inner_code=@product_inner_code ", new { itemGroup.Key.product_inner_code });
if (moq == null)
{
throw new Exception("未查询到商品moq");
}
// 计算差额,补齐 moq
var count_difference = moq - data_detailed_list.Sum(s => s.quantity);
if (count_difference > 0)
{
var count_difference_index = 0;
while (count_difference > 0)
{
data_detailed_list[count_difference_index].quantity++;
if (count_difference_index >= (data_detailed_list.Count - 1))
{
count_difference_index = 0;
}
else
{
count_difference_index++;
}
count_difference--;
}
}
}
}
else // 下一个供应链长度
{
// 查询交期
var max_delivery = conn.QuerySingleOrDefault<int?>(" select max('supplier_delivery' + `transfer_delivery`) from dc_base_sku where product_inner_code=@product_inner_code ", new { itemGroup.Key.product_inner_code });
if (max_delivery == null)
{
throw new Exception("未查询到交期");
}
// 计算预计下单数量
var sum_quantity = max_delivery * (itemGroup.Max(s => s.product_sales) * item_rule.sales_ratio);
if (sum_quantity <= 0)
{
throw new Exception("经过计算,无需下单");
}
foreach (var item in itemGroup.AsEnumerable())
{
data_detailed_list.Add(new auto_first_order_detailed_dto
{
bailun_sku = item.bailun_sku,
quantity = 0
});
}
var sum_quantity_index = 0;
while (sum_quantity > 0)
{
data_detailed_list[sum_quantity_index].quantity++;
if (sum_quantity_index >= (data_detailed_list.Count - 1))
{
sum_quantity_index = 0;
}
else
{
sum_quantity_index++;
}
sum_quantity--;
}
// 过滤掉没分配到需要下单的
data_detailed_list = data_detailed_list.Where(s => s.quantity > 0).ToList();
}
if (data_detailed_list == null || data_detailed_list.Count <= 0)
{
throw new Exception("计算完发现没有需求");
}
int purchase_advise_id = conn.Insert<dc_auto_purchase_advise>(new dc_auto_purchase_advise { buy_sys_plan_no = "自动下首单", create_time = DateTime.Now, no = purchase_advise.MaxNo() }, t) ?? 0;
foreach (var item in data_detailed_list)
{
conn.Insert(new dc_auto_purchase_advise_detailed
{
bailun_sku = item.bailun_sku,
warehouse_code = itemGroup.Key.warehouse_code,
quantity_init_advise = item.quantity,
quantity_actual = item.quantity,
main_id = purchase_advise_id,
forecast_formula = "",
fit_forecast_formula = "",
ispush = 0,
type = 4,
product_inner_code = itemGroup.Key.product_inner_code,
good_sku_codes = "",
purchase_type_jit = 3
}, t);
}
}
catch (Exception ex)
{
err_count = true;
conn.Insert(new dc_task_error_log
{
message = $"【商品sku】:【{itemGroup.Key.product_inner_code}】【{itemGroup.Key.warehouse_code}】" + ex.Message,
stack_trace = ex.StackTrace,
task_name = "auto_first_order_GeneratePurchaseAdvise",
date = DateTime.Now
}, t);
}
}
if (err_count)
{
t.Rollback();
}
else
{
t.Commit();
}
}
}
}
} }
} }
using System;
using System.Collections.Generic;
using System.Text;
namespace AutoTurnOver.Models
{
public class dc_auto_first_order_rule
{
public int id { get; set; }
public int source { get; set; }
public string warehouse_type { get; set; }
public string brand { get; set; }
public decimal quantity { get; set; }
/// <summary>
/// 下单类型 1=固定数量 2=供应链长度
/// </summary>
public int order_type { get; set; }
/// <summary>
/// 是否自动凑商品moq
/// </summary>
public bool has_collect { get; set; }
/// <summary>
/// sku数量下限
/// </summary>
public int lower_limit_sku_count { get; set; }
/// <summary>
/// 商品日均下限
/// </summary>
public int lower_limit_sales { get; set; }
/// <summary>
/// 日均销量比例
/// </summary>
public decimal sales_ratio { get; set; }
}
}
...@@ -17,7 +17,27 @@ namespace AutoTurnOver.Models ...@@ -17,7 +17,27 @@ namespace AutoTurnOver.Models
/// 运输方式 1=陆运 2=海运 3=空运 4=铁路运输 /// 运输方式 1=陆运 2=海运 3=空运 4=铁路运输
/// </summary> /// </summary>
public int sendtype { get; set; } public int sendtype { get; set; }
public DateTime? order_time { get; set; } public DateTime order_time { get; set; }
/// <summary>
/// 内部商品编码
/// </summary>
public string product_inner_code { get; set; }
/// <summary>
/// 商品日均销量
/// </summary>
public decimal product_sales { get; set; }
/// <summary>
/// 开发来源
/// </summary>
public int source { get; set; }
/// <summary>
/// 品牌
/// </summary>
public string brand { get; set; }
} }
public class dc_auto_first_order_sku_input_dto public class dc_auto_first_order_sku_input_dto
...@@ -26,7 +46,41 @@ namespace AutoTurnOver.Models ...@@ -26,7 +46,41 @@ namespace AutoTurnOver.Models
public int sendtype { get; set; } public int sendtype { get; set; }
public List<string> detailed { get; set; } public List<detailed_dto> detailed { get; set; }
public class detailed_dto
{
public string bailun_sku { get; set; }
/// <summary>
/// 内部商品编码
/// </summary>
public string product_inner_code { get; set; }
/// <summary>
/// 商品日均销量
/// </summary>
public decimal product_sales { get; set; }
/// <summary>
/// 开发来源
/// </summary>
public int source { get; set; }
/// <summary>
/// 品牌
/// </summary>
public string brand { get; set; }
}
}
/// <summary>
/// 自动下单明细
/// </summary>
public class auto_first_order_detailed_dto
{
public string bailun_sku { get; set; }
public decimal quantity { get; set; }
} }
} }
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