
## 二开实战:如何在移动表单中自动优先级取价
> 本实战根据如下二开方案中的**1.自动优先级取价**,演示如何从销售订单、基础资料客户、基础资料物料等数据源获取数据并赋值给取价参数,从而完成取价逻辑
> 二开方案:如何在移动表单中调用接口获取销售价目表、销售折扣表(https://vip.kingdee.com/article/449530620910173440)
### 1. 前提准备
目前已维护好相关价目表数据,已打开自动优先级取价(参数设置-供应链-销售管理-取价)。PC端创建一张销售订单,测试当前物料取价是否正常:在分录中输入好物料信息,当输入数量后,自动带出对应价格(如下图)

此时,将所有分录的含税单价全部清空(如下图),然后暂存该单据,测试根据二开方案是否可以进行自动优先级取价

### 2. 模拟取价
操作步骤:
1. 查询到当前销售订单的主键ID备用(通过T_SAL_ORDER表)
2. 编写插件,根据需要实例化取价参数,然后调用SaleGetPriceAutoHelper.GetSalePriceRustltByAuto完成取价
3. 创建移动表单,增加按钮用于触发取价即可,将插件注册到该表单并启用

代码参考如下:
```
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Mobile.PlugIn;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.K3.Core.Mobile.Utils;
using Kingdee.K3.Core.SCM.Args;
using Kingdee.K3.SCM.ServiceHelper;
using System;
using System.Collections.Generic;
using System.Linq;
namespace YourNamespace
{
public class PriceDemo : AbstractMobilePlugin
{
public override void ButtonClick(ButtonClickEventArgs e)
{
base.ButtonClick(e);
if (e.Key == "FBUTTON")
{
OrdersPriceMapping();
}
}
public void OrdersPriceMapping()
{
// 获取销售订单元数据
var salOrderMetadata = MetaDataServiceHelper.GetFormMetaData(this.Context, "SAL_SaleOrder");
// 销售订单数据包
// 备注:当前以某个订单(主键=101158)举例,你在使用时根据需要灵活赋值各项即可
DynamicObject doSalOrder = BusinessDataServiceHelper.Load(this.Context, new object[] { 101158 }, salOrderMetadata.BusinessInfo.GetDynamicObjectType()).FirstOrDefault();
// 财务信息子单据头数据
DynamicObject doSaleOrderFinance = (doSalOrder["SaleOrderFinance"] as DynamicObjectCollection).FirstOrDefault();
// 结算币别
long settleCurrId = doSaleOrderFinance.GetPropertyValue<long>("SettleCurrId_Id");
// 销售组
long saleGroupId = doSalOrder.GetPropertyValue<long>("SaleGroupId_Id");
// 销售组织
long saleOrgId = doSalOrder.GetPropertyValue<long>("SaleOrgId_Id");
// 销售部门
long saleDeptId = doSalOrder.GetPropertyValue<long>("SaleDeptId_Id");
// 销售员
long salerId = doSalOrder.GetPropertyValue<long>("SalerId_Id");
// 基础资料-客户
var doCust = doSalOrder["CustId"] as DynamicObject;
// 客户ID
long custId = doCust.GetPropertyValue<long>("Id");
// 客户类别
string custTypeId = doCust.GetPropertyValue<string>("CustTypeId_Id");
// 客户分组:由于默认的销售订单上的客户字段的引用属性不包含 客户基础资料里的【基本信息.客户分组】,因此需要根据custId加载BD_Customer数据包,拿到客户分组
var customerMetadata = MetaDataServiceHelper.GetFormMetaData(this.Context, "BD_Customer");
var doCustomer = BusinessDataServiceHelper.Load(this.Context, new object[] { custId }, customerMetadata.BusinessInfo.GetDynamicObjectType()).FirstOrDefault();
long custGroupId = doCustomer.GetPropertyValue<long>("FGroup_Id");
// 日期
DateTime date = doSalOrder.GetPropertyValue<DateTime>("Date");
// 是否含税
bool isIncludedTax = doSaleOrderFinance.GetPropertyValue<bool>("IsIncludedTax");
// 价目表
long priceListId = doSaleOrderFinance.GetPropertyValue<long>("PriceListId_Id");
// 订单明细分录
DynamicObject[] entryData = (doSalOrder["SaleOrderEntry"] as DynamicObjectCollection).ToArray();
// 取价参数List
List<GetPriceArgs> list = new List<GetPriceArgs>();
// 循环加入子项
for (var i = 0; i < entryData.Length; i++)
{
//销售订单订单明细中的该分录行数据
var data = entryData[i];
//该分录行的物料数据
var material = data["MaterialId"] as DynamicObject;
// 构建单个取价参数
var args = new GetPriceArgs
{
// 源单据(从销售订单)中的结算币别ID、销售组ID、销售组织ID等
SettleCurrId = settleCurrId,
SaleGroupId = saleGroupId,
SaleOrgId = saleOrgId,
SaleDeptId = saleDeptId,
SalerId = salerId,
CustId = custId,
CustTypeId = custTypeId,
CustGroupId = custGroupId,
Date = date,
IsIncludedTax = isIncludedTax,
PriceListId = priceListId,
// 当前物料的信息(从基础资料-物料)
MaterialId = material.GetPropertyValue<long>("Id"),
Material = material,
MasterId = material.GetPropertyValue<long>("msterID"),
MaterialGroupId = material.GetPropertyValue<long>("MaterialGroup_Id"),
// 物料明细行号
Row = i
};
// 计价单位、销售单位的特殊处理
var materialSaleEntitys = material.GetPropertyValue<DynamicObjectCollection>("MaterialSale");
if (materialSaleEntitys != null && materialSaleEntitys.Any())
{
var materialSaleEntity = materialSaleEntitys[0];
// 物料上的计价单位
args.PriceUnitId = materialSaleEntity.GetPropertyValue<long>("SalePriceUnitId_Id");
}
// 如果找不到单据上的计价单位值,那么跟物料计价单位保持一致
args.UnitId = data.GetPropertyValue("PriceUnitId", args.PriceUnitId);
// 数量:如果找不到单据上的计价数量值,那么默认为1
args.Qty = data.GetPropertyValue("PriceUnitQty", 1M);
// 是否免费(赠品)
args.IsFree = data.GetPropertyValue<bool>("IsFree");
// 是否已取到价(默认为false)
args.IsGetPrice = false;
// 启用批号取价时,批号应该为空,但不能为Null
args.Lot = "";
// 加入list
list.Add(args);
}
var results = GetPrice(list);
}
private List<PriceResult> GetPrice(List<GetPriceArgs> priceArgs)
{
var getPriceArgs = SaleGetPriceAutoHelper.GetSalePriceRustltByAuto(this.Context, priceArgs, false);
List<PriceResult> priceResults = new List<PriceResult>();
if (getPriceArgs == null)
{
return priceResults;
}
foreach (var priceArg in getPriceArgs)
{
priceResults.Add(priceArg.PirceResult);
}
return priceResults;
}
}
}
```
调试取价结果:

解析:
取价完成后,PriceList保存当前取到的价目表信息、PriceResult保存当前取到的价格数据、IsGetPrice=true标志当前已经取价完成。
还需要注意,PriceResult存在TaxPrice、Price属性,根据是否含税取对应价格即可。
### 3. 总结
以上步骤即可完成自动优先级取价逻辑,更多取价方式请参考 二开方案:如何在移动表单中调用接口获取销售价目表、销售折扣表(https://vip.kingdee.com/article/449530620910173440)。