智能商贸-day10-采购单

1.1. 组合关系-采购订单模型完整代码

1.1.1. Purchasebill组合关系的一方

/**
 * 
 * 采购订单:组合关系的一方
 * 
 */
@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;
}

1.1.2. purchasebillitem组合关系的多方

/**
 * 
 * 采购订单明细:组合关系的多方
 * 
 */
@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;// 组合关系,非空

1.2. 订单列表查询

1.2.1. 订单列表显示

  1. purchasebill.jsp展示
交易时间 供应商 采购员 总数量 总金额 状态
  1. purchasebill.js
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]; }

1.2.2. 查询条件的添加

  1. purchasebill.jsp

日期 : - 状态 : 查找
  1. purchasebillQuery.java
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略…
}

1.2.3. 查询的日期问题

if(endDate != null) {
   Date date = new Date(endDate.getTime() +  24 * 60 * 60 * 1000);
   System.out.println("date:" + date.toLocaleString());
}
  1. 方案2:JDK实现
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());
}
  1. 方案3:org.apache.commons.lang.time.DateUtils
    当前日期业务最简单的方法
if(endDate != null) {	
   Date date = DateUtils.addDays(endDate, 1);
}
  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;
}

1.1. 采购订单的form表单

purchasebill.jsp
交易时间:
供应商:
采购员:

1.1.1. UtilController后台下拉支持

  1. Supplier下拉支持
    SupplierController.java
    //返回所有的供应商
@RequestMapping("/findAllSupplier")
@ResponseBody
public List findAllSupplier(){
    return  supplierService.findAll();
}

  1. Employee下拉支持
    EmployeeRepository
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();
}

1.1.2. 数据保存

解决方案:
EmployeeService

@Override
public void save(Purchasebill purchasebill) {
    //当前登录用户为录入人
    Employee loginUser = UserContext.getUser();
    purchasebill.setInputUser(loginUser);
    super.save(purchasebill);
}

1.2. 明细数据的操作

1.2.1. 引入支持的js

注意引入的位置


    purchasebill管理
    <%@include file="/WEB-INF/views/head.jsp" %>
    
    
    
    
    

1.2.2. 拷备案例中数据

案例文件:CellEditDemo.html

  1. purchasebill.jsp


  1. purchasebill.js
    (持备过来的还不可以使用,我们下面对它做相应的代码解释)

下面是完整拷备的详细解释

//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();

1.2.3. 基本数据准备

  1. 修改明细数据为产品数据
//defaultRow:默认的行(每次添加一行都是把这个数据加进去)
//  分别加上产品id,产品颜色,产品图片,数量,价格,总价与备注
var gridItems = $("#gridItems"),
defaultRow = { productId: "", productColor: "", productImage: "",num: 0, price: 0, amount: 0, descs: "" },
insertPosition = "bottom";
  1. 后台返回所有产品(可供选择)
@Controller
@RequestMapping("/util")
public class UtilController extends BaseController {
   ...
    @Autowired
    private IProductService productService;

    ...

    @RequestMapping("/getProduct")
    @ResponseBody
    public List getProduct(){
        return productService.findAll();
    }
}
  1. 选择产品进行展示
//对于明细数据的初始化
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; };

1.2.4. 为按钮添加事件

//事件注册的方法
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);
    });
};

1.2.5. 采购单保存

  1. 提交采购明细数据
    咱们提交明细要注意提交的数据格式:
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');
       }
   })
},
  1. 后台进行保存
//添加或者修改
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");
},
  1. 修改时回显明细
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');
    }
},
  1. 解决n-to-n的相应问题
//这里准备一个方法,所有方法执行前都会执行它
@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;
}

你可能感兴趣的:(智能商贸-day10-采购单)