/**
*
* 采购订单:组合关系的一方
*
*/
@Entity
@Table(name = "purchasebill")
public class Purchasebill extends BaseDomain {
private Date vdate;// 交易时间 -> 需要录入(时间set的时候加上@DateTimeFormat(pattern = "yyyy-MM-dd"))
private BigDecimal totalAmount; //总金额 -> 明细计算
private BigDecimal totalNum; //总数量 -> 明细计算
private Date inputTime = new Date(); //录入时间 ->当前系统时间
private Date auditorTime; //审核时间 -> 可以为空,审核时自己生成
/**
* 0待审,1已审,-1作废
*/
private Integer status = 0; //单据状态 -> 默认待审
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "supplier_id")
private Supplier supplier;// 多对一,非空 供应商(需要选择)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "auditor_id")
private Employee auditor;// 多对一,可以为空
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "inputUser_id")
private Employee inputUser;// 多对一,非空 录入人 -> 登录用户就是录入人
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "buyer_id")
private Employee buyer;// 多对一,非空 采购员 -> 需要
// 一般组合关系使用List
@OneToMany(cascade = CascadeType.ALL, mappedBy = "bill", fetch = FetchType.LAZY, orphanRemoval = true)
private List items = new ArrayList();
…
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
public Date getVdate() {
return vdate;
}
@DateTimeFormat(pattern = "yyyy-MM-dd")
public void setVdate(Date vdate) {
this.vdate = vdate;
}
/**
*
* 采购订单明细:组合关系的多方
*
*/
@Entity
@Table(name = "purchasebillitem")
public class purchasebillitem extends BaseDomain {
private BigDecimal price; //价格
private BigDecimal num; //数量
private BigDecimal amount; //小计 = 价格*数量
private String descs; //描述
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "product_id")
private Product product;// 多对一,非空 产品
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "bill_id")
@JsonIgnore //生成json的时候忽略这个属性
private Purchasebill bill;// 组合关系,非空
交易时间
供应商
采购员
总数量
总金额
状态
function formatObj(data) {
if(data){
return data.name;
}
}
function formatEmp(data) {
if(data){
return data.username;
}
}
function formatStatus(action) {
var data = {
0:"待审",
1:"已审",
"-1":"作废"
};
return data[action];
}
package cn.itsource.pss.query;
import cn.itsource.pss.domain.Purchasebill;
import com.github.wenhao.jpa.Specifications;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
public class PurchasebillQuery extends BaseQuery {
//SpringMVC接收日期的格式设置(建议写在setter上)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date beginDate;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endDate;
private Integer status;
@Override
public Specification createSpecification(){
//根据条件把数据返回即可
Specification spec = Specifications.and()
.eq(status!=null,"status",status )//等于
.ge(beginDate!=null, "vdate",beginDate) //大于等于
.le(endDate!=null, "vdate",endDate) //小于等于
.build();
return spec;
}
//getter,setter略…
}
if(endDate != null) {
Date date = new Date(endDate.getTime() + 24 * 60 * 60 * 1000);
System.out.println("date:" + date.toLocaleString());
}
if(endDate != null) {
System.out.println("endDate:"+this.endDate.toLocaleString());
Calendar calendar = Calendar.getInstance();
calendar.setTime(endDate);
calendar.add(Calendar.DAY_OF_MONTH, 1);
System.out.println("endDate:"+calendar.getTime().toLocaleString());
}
if(endDate != null) {
Date date = DateUtils.addDays(endDate, 1);
}
@Override
public Specification createSpecification(){
//如果日期不为空,结束日期加1
Date tempDate = null;
if(endDate!=null){
tempDate = DateUtils.addDays(endDate, 1);
}
//根据条件把数据返回即可
Specification spec = Specifications.and()
.eq(status!=null,"status",status )
.ge(beginDate!=null, "vdate",beginDate) //大于等于
.lt(endDate!=null, "vdate",tempDate) //小于
.build();
return spec;
}
purchasebill.jsp
@RequestMapping("/findAllSupplier")
@ResponseBody
public List findAllSupplier(){
return supplierService.findAll();
}
public interface EmployeeRepository extends BaseRepository {
…
@Query("select o from Employee o where o.department.name=?1")
List getEmpByDept(String deptName);
}
EmployeeService
@Override
public List getBuyer() {
return employeeRepository.getEmpByDept("采购部");
}
EmployeeController
@RequestMapping("/getBuyer")
@ResponseBody
public List getBuyer(){
return employeeService.getBuyer();
}
解决方案:
EmployeeService
@Override
public void save(Purchasebill purchasebill) {
//当前登录用户为录入人
Employee loginUser = UserContext.getUser();
purchasebill.setInputUser(loginUser);
super.save(purchasebill);
}
注意引入的位置
purchasebill管理
<%@include file="/WEB-INF/views/head.jsp" %>
案例文件:CellEditDemo.html
下面是完整拷备的详细解释
//gridItems:拿到咱们的明细数据
//defaultRow:默认的行(每次添加一行都是把这个数据加进去)
//insertPosition:代表数据插入的位置(bottom代表在底部)
var gridItems = $("#gridItems"),
defaultRow = { ID: "", Code: "", Name: "", StandardModel: "", ApplyCount: "", Remark: "", Stocks: "" },
insertPosition = "bottom";
//对于明细数据的初始化
var dgInit = function () {
//grid中的每一列的配置
var getColumns = function () {
var result = [];
var normal = [
{
field: 'Code', title: '物资编码', width: 180,
editor: {
type: "validatebox",
options: {
required: true
}
}
},
{
field: 'Name', title: '名称', width: 180,
editor: {
type: "validatebox",
options: {
required: false,
readonly: false
}
}
},
{
field: 'StandardModel', title: '规格型号(只读)', width: 100,
editor: {
type: "validatebox",
options: {
required: false,
readonly: true
}
}
},
{
field: 'ApplyCount', title: '申请数量', width: 100,
editor: {
type: "numberbox",
options: {
required: true
}
}
},
{
field: 'Remark', title: '备注', width: 100,
editor: {
type: "text"
}
},
{
field: 'Stocks', title: '库存数量', width: 100,
editor: {
type: "numberbox",
options: {
readonly: false
}
}
}
];
result.push(normal);
return result;
};
//grid中基本配置
var options = {
idField: "ID",
rownumbers: true,
fitColumns: true,
//fit: true,
//border: false,
toolbar:"#itemBtns",
height:300,
singleSelect: true,
columns: getColumns(),
//表示开启单元格编辑功能
enableCellEdit: true
};
//创建一个grid
gridItems.datagrid(options);
};
//根据这个确定位置插件在上面还是下面(和上面的insertPosition匹配)
var getInsertRowIndex = function () {
return insertPosition == "top" ? 0 : gridItems.datagrid("getRows").length;
}
//事件注册的方法
var buttonBindEvent = function () {
//添加事件(现在没有,先不用管)
$("#btnInsert").click(function () {
var targetIndex = getInsertRowIndex(), targetRow = $.extend({}, defaultRow, { ID: $.util.guid() });
gridItems.datagrid("insertRow", { index: targetIndex, row: targetRow });
gridItems.datagrid("editCell", { index: 0, field: "Code" });
});
//保存数据的事件(现在没有,先不用管)
$("#btnSave").click(function () {
var rows = gridItems.datagrid("getRows"), len = rows.length;
for (var i = 0; i < len; i++) {
gridItems.datagrid("endEdit", i);
}
});
};
//dgInit:执行初始化的方法 buttonBindEvent:注册相应的按钮事件
dgInit(); buttonBindEvent();
//defaultRow:默认的行(每次添加一行都是把这个数据加进去)
// 分别加上产品id,产品颜色,产品图片,数量,价格,总价与备注
var gridItems = $("#gridItems"),
defaultRow = { productId: "", productColor: "", productImage: "",num: 0, price: 0, amount: 0, descs: "" },
insertPosition = "bottom";
@Controller
@RequestMapping("/util")
public class UtilController extends BaseController {
...
@Autowired
private IProductService productService;
...
@RequestMapping("/getProduct")
@ResponseBody
public List getProduct(){
return productService.findAll();
}
}
//对于明细数据的初始化
var dgInit = function () {
//grid中的每一列的配置
var getColumns = function () {
var result = [];
var normal = [
{
field: 'productId', title: '产品', width: 80,
editor: {
type: "combobox",
options: {
valueField:'id',
textField:'name',
panelHeight:'auto',
url:'/util/getProduct',
required: true
}
},
formatter:function(value,row){
return value.name;
}
},
{
field: 'productColor', title: '颜色', width: 80,
formatter:function(value,row){
if(row && row.productId){
return "";
}
}
},
{
field: 'productImage', title: '图片', width: 80,
formatter:function(value,row){
console.debug(row);
if(row && row.productId){
return "";
}
}
},
{
field: 'num', title: '数量', width: 100,
editor: {
type: "numberbox",
options: {
required: true
}
}
},
{
field: 'price', title: '价格', width: 100,
editor: {
type: "numberbox",
options: {
required: true
}
}
},
{
field: 'amount', title: '小计', width: 100,
formatter:function(value,row){
if(row.num && row.price){
var amount = (row.num * row.price).toFixed(2);
return amount;
}
return 0;
}
},
{
field: 'descs', title: '备注', width: 100,
editor: {
type: "text"
}
}
];
result.push(normal);
return result;
};
//事件注册的方法
var buttonBindEvent = function () {
//添加事件(和之前一样,可以不用管)
$("#btnInsert").click(function () {
var targetIndex = getInsertRowIndex(), targetRow = $.extend({}, defaultRow, { ID: $.util.guid() });
gridItems.datagrid("insertRow", { index: targetIndex, row: targetRow });
gridItems.datagrid("editCell", { index: targetIndex, field: "productId" });
});
//删除一行数据
$("#btnRemove").click(function () {
var row = gridItems.datagrid("getSelected");
//拿到对应的行
var index = gridItems.datagrid("getRowIndex",row);
//删除这一行
gridItems.datagrid("deleteRow",index);
});
};
save:function () {
var url = "/purchasebill/save";
var id = $("#purchasebillId").val();
if(id){
url = "/purchasebill/update?cmd=update";
}
purchasebillForm.form('submit', {
url:url,
onSubmit: function(param){
//这里加上param这个参数,为它设置值,就可以做额外的参数提交
//拿到当前页的所有参数 并进行名称修改 items[0].product.id /item[1].price,...
var rows = gridItems.datagrid('getRows');
//param.items[0].product.id = 1;
for (var i = 0; i < rows.length; i++) {
var rowData = rows[i];
param["items[" + i + "].product.id"] = rowData.productId.id;
param["items[" + i + "].price"] = rowData.price;
param["items[" + i + "].num"] = rowData.num;
param["items[" + i + "].descs"] = rowData.descs;
//完成当前 这一行数据的验证
if(!gridItems.datagrid("validateRow",i)){
alert("你的明细数据有还有问题!");
return false;
}
}
return purchasebillForm.form("validate");
},
success:function(data){
var result = JSON.parse(data);//转成相应的json数据
if(result.success) {
$('#purchasebillGrid').datagrid('reload');
}else{
$.messager.alert('提示信息','操作失败!,原因:'+result.msg,"error");
}
purchasebillDialog.dialog('close');
}
})
},
//添加或者修改
private Map saveOrUpdate( Purchasebill purchasebill){
Map map = new HashMap<>();
try {
//1 准备总数量与总金额
BigDecimal totalAmount = new BigDecimal(0);
BigDecimal totalNum = new BigDecimal(0);
//2 拿到相应的明细
List items = purchasebill.getItems();
for (Purchasebillitem item : items) {
item.setBill(purchasebill);//让一方也多方也建立关系
item.setAmount(item.getNum().multiply(item.getPrice()));//计算明细小计
//总数量与总金额累加
totalAmount = totalAmount.add(item.getAmount());
totalNum = totalNum.add(item.getNum());
}
//3 设置总数量与总金额
purchasebill.setTotalAmount(totalAmount);
purchasebill.setTotalNum(totalNum);
purchasebillService.save(purchasebill);
map.put(SUCCESS, true);
} catch (Exception e) {
e.printStackTrace();
map.put(SUCCESS, false);
map.put("msg", e.getMessage());
}
return map;
}
1.2.6. 其它细节处理
1. 添加时清除明细
add:function () {
//隐藏有data-save属性的元素
$("*[data-save]").show();
//禁用有data-save属性的input元素的验证功能
$("*[data-save] input").validatebox("enableValidation");
//弹出表单窗口
purchasebillForm.form("clear");//清除数据
//把明细的数据清空
gridItems.datagrid("loadData", []);
purchasebillDialog.dialog("center").dialog("open");
},
edit:function () {
//弹出表单窗口
//选中了某一条数据才删除
var row = purchasebillGrid.datagrid("getSelected");
if(row) {
//隐藏有data-save属性的元素
$("*[data-save]").hide();
//禁用有data-save属性的input元素的验证功能
$("*[data-save] input").validatebox("disableValidation");
purchasebillForm.form("clear");//清除数据
purchasebillDialog.dialog("center").dialog("open");
//单独解决供应商与采购员的回显问题
if (row.supplier) {
row["supplier.id"] = row.supplier.id;
}
if (row.buyer) {
row["buyer.id"] = row.buyer.id;
}
//加载相应的数据(要看product的名称是否可以对应上)
for (var i = 0; i < row.items.length; i++) {
row.items[i].productId = row.items[i].product;
}
var items = $.extend([], row.items);
gridItems.datagrid("loadData", items); //必需在弹出界面之后执行
//为form加载数据
purchasebillForm.form("load",row);
}else{
$.messager.alert('提示信息','请选择一行再进行修改!','info');
}
},
//这里准备一个方法,所有方法执行前都会执行它
@ModelAttribute("edit Purchasebill")
public Purchasebill beforeEdit(Long id, String cmd){
//有id的时候-> 修改功能
if(id!=null && "update".equals(cmd)) {
Purchasebill purchasebill = purchasebillService.findOne(id);
//把这个要修改的关联对象设置为null,可以解决n-to-n的问题
//把有关系的对象移除
purchasebill.setSupplier(null);
purchasebill.setBuyer(null);
purchasebill.getItems().clear();
return purchasebill;
}
return null;
}