开发检测题目
一、出库申请单
1、
表头字段:人员personnel(参照人员基本信息表)、部门department(参照组织-部门)、类别category(下拉:项目出库申请、其他出库申请)、总数量sumnum(数值,不可编辑)、是否已出库iswarehousing(逻辑型,不可编辑)
表体字段:客户customer(参照客户基本信息表)、数量num(数值型)、含税单价taxprice(数值型)、无税单价notaxprice(数值型不可编辑)、税率taxrate(数值型)、税额tax(数值型不可编辑)、无税金额notaxmny(数值型,不可编辑)、含税金额taxmny(数值型,不可编辑)
2、选择人员字段,自动带出人员所在的部门,并赋值到部门字段
//人员编辑后带出人员所在部门
private void personnelBringoutDepartment(CardHeadTailAfterEditEvent e) throws BusinessException{
//获取表头人员字段的值
String pk_psndoc = NullValueUtils.getNullStringValue(e.getBillCardPanel().getHeadItem("personnel").getValueObject());
SqlBuilder sql = new SqlBuilder();
sql.append(" select pk_dept");
sql.append(" from hi_psnjob");
sql.append(" where nvl(dr,0) = 0");
sql.append(" and pk_psndoc = '" + pk_psndoc + "'");
//获取数据库语句查询出来的部门字段的值
String pk_dept = NullValueUtils.getNullStringValue(getService().executeQuery(sql.toString(), new ColumnProcessor()));
//给部门字段赋值
e.getBillCardPanel().setHeadItem("department", pk_dept);
}
//前端使用数据库查询语句必须增加的方法
private IUAPQueryBS service;
private IUAPQueryBS getService() {
if (service == null) {
service = NCLocator.getInstance().lookup(IUAPQueryBS.class);
}
return service;
}
3、选择人员时,根据选中的部门进行过滤,只能选择此部门下的人员
package nc.ui.yhlypx.kfcksqd.ace.handler;
import nc.ui.pub.beans.UIRefPane;
import nc.ui.pubapp.uif2app.event.IAppEventHandler;
import nc.ui.pubapp.uif2app.event.card.CardHeadTailBeforeEditEvent;
import nc.ui.yhlypx.util.NullValueUtils;
import nc.vo.pub.lang.UFBoolean;
/**
* 单据表头表尾字段编辑前事件处理类
*
* @since 6.0
* @version 2022-09-14
* @author lp
*/
public class AceHeadTailBeforeEditHandler implements IAppEventHandler<CardHeadTailBeforeEditEvent> {
@Override
public void handleAppEvent(CardHeadTailBeforeEditEvent e) {
String key = e.getKey();
if(key.equals("personnel")){
personnelfilter(e);
}
e.setReturnValue(UFBoolean.TRUE.booleanValue());
}
/**
* @describe:人员编辑前过滤只查询该部门下的人员
* @date:2023-03-21
*/
private void personnelfilter(CardHeadTailBeforeEditEvent e){
String dept = NullValueUtils.getNullStringValue(e.getBillCardPanel().getHeadItem("department").getValueObject());
if(!dept.equals("")){
UIRefPane refPane = (UIRefPane) e.getBillCardPanel().getHeadItem("personnel").getComponent();
refPane.getRefModel().setWherePart("bd_psnjob.pk_dept = '" + dept + "'");
}
}
}
4、无税单价 = 含税单价/(1+税率)
含税金额 = 数量*含税单价
无税金额=无税单价 * 税率
税额= 含税金额-无税金额
package nc.ui.yhlypx.kfcksqd.ace.handler;
import nc.ui.pubapp.uif2app.event.IAppEventHandler;
import nc.ui.pubapp.uif2app.event.card.CardBodyAfterEditEvent;
import nc.ui.yhlypx.util.NullValueUtils;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
public class AceBodyAfterEditHandler implements
IAppEventHandler<CardBodyAfterEditEvent> {
@Override
public void handleAppEvent(CardBodyAfterEditEvent e) {
//获取当前编辑字段的名称
String key = e.getKey();
//获取当前编辑行
int row = e.getRow();
try {
if(key.equals("num") || key.equals("taxprice") || key.equals("taxrate")){
//计算无税单价、含税金额、无税金额、税额
calculate(e,row);
}
} catch (BusinessException e1) {
ExceptionUtils.wrappBusinessException(e1.getMessage());
}
}
private void calculate(CardBodyAfterEditEvent e, int row) throws BusinessException{
//获取当前编辑行对应的编码为taxprice字段的值
UFDouble taxprice = NullValueUtils.getNullUFdoubleValue(e.getBillCardPanel().getBodyValueAt(row, "taxprice"));
//获取当前编辑行对应的编码为taxrate字段的值
UFDouble taxrate = NullValueUtils.getNullUFdoubleValue(e.getBillCardPanel().getBodyValueAt(row, "taxrate"));
//获取当前编辑行对应的编码为num字段的值
UFDouble num = NullValueUtils.getNullUFdoubleValue(e.getBillCardPanel().getBodyValueAt(row, "num"));
//计算无税单价
UFDouble notaxprice = taxprice.div(UFDouble.ONE_DBL.add(taxrate.doubleValue()/100));
//把算出的结果(notaxprice)赋给当前行上的无税单价字段("notaxprice")
e.getBillCardPanel().setBodyValueAt(notaxprice, row, "notaxprice");
//计算含税金额
UFDouble taxmny = num.multiply(taxprice);
//把算出的结果(taxmny)赋给当前行上的含税金额字段("taxmny")
e.getBillCardPanel().setBodyValueAt(taxmny, row, "taxmny");
//计算无税金额
UFDouble notaxmny = notaxprice.multiply(taxrate.doubleValue()/100);
//把算出的结果(notaxmny)赋给当前行上的无税金额字段("notaxmny")
e.getBillCardPanel().setBodyValueAt(notaxmny, row, "notaxmny");
//计算税额
UFDouble tax = taxmny.sub(notaxmny);
//把算出的结果(tax)赋给当前行上的税额字段("tax")
e.getBillCardPanel().setBodyValueAt(tax, row, "tax");
}
}
5、保存时校验:表体客户不能重复,如果重复则提示具体的哪行与哪行重复
//新增保存校验:表体客户不能重复
private void saveCheckRepeatCustomer(AggKfcksqdVO aggvo) throws BusinessException{
//通过aggvo获取表体
KfcksqdBVO[] bvos = (KfcksqdBVO[]) aggvo.getChildren(KfcksqdBVO.class);
//如果表体数据不为空
if(bvos != null && bvos.length > 0){
//创建map集合,键为还款编号,值为重复行号集合
Map<String, List<String>> map = new HashMap<String, List<String>>();
//遍历出库申请单表体
for(int i = 0; i < bvos.length; i++){
//如果客户不为空
if(bvos[i].getCustomer() != null && !bvos[i].getCustomer().equals("")){
//依次获取各行行号
String rowno = bvos[i].getRowno();
//依次获取各行客户
String customer = bvos[i].getCustomer();
//如果map的键中包含该行客户字段
if(map.containsKey(customer)){
//获取该行客户在map集合中对应的值
List<String> list = map.get(customer);
//该行行号添加到该行重复行号集合中
list.add(rowno);
//如果map的键中不包含该行客户字段
}else{
//新建一个存放行号的集合
List<String> list = new ArrayList<>();
//该行行号添加到新建的集合中
list.add(rowno);
//该行客户和新建的集合关联
map.put(customer, list);
}
}
}//得到了客户和对应重复行号集合的map
//提示信息初始化为空字符串
String str = "";
//遍历map集合中的键
for (String customer : map.keySet()) {
//获取该行客户在map集合中对应的值
List<String> list = map.get(customer);
//如果该行重复行号集合的大小大于1(有和该行客户字段重复的行)
if(list != null && list.size() > 1){
//重复行号初始化为空字符串
String rownostr = "";
//遍历存放重复行号的集合
for (int i = 0; i < list.size(); i++) {
//依次获取重复行号的集合中的值
String string = list.get(i);
//如果是第一行
if(i == 0){
//把重复行号集合中的第一个值赋给rownostr
rownostr = string;
//如果不是第一行
} else {
//重复行号集合中的第一个值拼接上依次获取重复行号的集合中的值
rownostr = rownostr+","+string;
}
}
//累加重复行提示信息
str = str+rownostr+"行号客户字段对应值重复;";
}
}//得到全部重复行的提示信息
//如果提示信息不为空
if(str != null && !"".equals(str)){
//把提示信息在前端输出
throw new BusinessException(str);
}
}
}
6、保存后将表体的数量进行汇总复制给表头总数量
//表体数量汇总表头
private void saveSum(AggKfcksqdVO aggvo) throws BusinessException{
//通过aggvo获取表体
KfcksqdBVO[] bvos = (KfcksqdBVO[]) aggvo.getChildren(KfcksqdBVO.class);
//[]这种情况不为空,但是不能进入循环,所以还要加上bvos.length > 0这个条件
if(bvos != null && bvos.length > 0){
//定义一个求和变量,初始化为0
UFDouble sum = UFDouble.ZERO_DBL;
//遍历表体
for (int i = 0; i < bvos.length; i++) {
//累加数量
sum = sum.add(NullValueUtils.getNullUFdoubleValue(bvos[i].getNum()));
}
//把累加数量赋值给表头的放款金额本币字段
aggvo.getParentVO().setSumnum(sum);
}
}
7、取消审批校验:如果是否出库为是,则提示“已经生成下游出库单,不可以取消审批”
package nc.bs.yhlypx.kfcksqd.ace.bp.rule.unapprove;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.ui.yhlypx.util.NullValueUtils;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.yhlypx.kfcksqd.AggKfcksqdVO;
public class UnapproveBeforeRule implements IRule<AggKfcksqdVO>{
@Override
public void process(AggKfcksqdVO[] aggvos) {
for(int i = 0; i < aggvos.length; i++){
try {
//取消审批校验是否生成下游出库单数据
unapproveCheck(aggvos[i]);
} catch (BusinessException e) {
ExceptionUtils.wrappBusinessException(e.getMessage());
}
}
}
//取消审批校验是否生成下游出库单数据
private void unapproveCheck(AggKfcksqdVO aggvo) throws BusinessException{
UFBoolean iswarehousing = NullValueUtils.getNullUFBooleanValue(aggvo.getParentVO().getIswarehousing());
if(iswarehousing.equals(UFBoolean.TRUE)){
throw new BusinessException("已经生成下游出库单,不可以取消审批!!!");
}
}
}
package nc.bs.yhlypx.kfcksqd.ace.bp;
import nc.bs.yhlypx.kfcksqd.ace.bp.rule.unapprove.UnapproveBeforeRule;
import nc.bs.yhlypx.kfcksqd.plugin.bpplugin.KfcksqdPluginPoint;
import nc.impl.pubapp.pattern.data.bill.template.UpdateBPTemplate;
import nc.impl.pubapp.pattern.rule.processer.CompareAroundProcesser;
import nc.vo.pub.VOStatus;
import nc.vo.yhlypx.kfcksqd.AggKfcksqdVO;
/**
* 标准单据弃审的BP
*/
public class AceKfcksqdUnApproveBP {
public AggKfcksqdVO[] unApprove(AggKfcksqdVO[] clientBills,
AggKfcksqdVO[] originBills) {
//出库单审批通过的对应的出库申请单不能弃审
UpdateBPTemplate<AggKfcksqdVO> bp = new UpdateBPTemplate<AggKfcksqdVO>(
KfcksqdPluginPoint.UPDATE);
this.addBeforeRule(bp.getAroundProcesser());
for (AggKfcksqdVO clientBill : clientBills) {
clientBill.getParentVO().setStatus(VOStatus.UPDATED);
}
AggKfcksqdVO[] returnVos = bp.update(clientBills, originBills);
return returnVos;
}
private void addBeforeRule(CompareAroundProcesser<AggKfcksqdVO> compareAroundProcesser) {
// TODO 自动生成的方法存根
compareAroundProcesser.addBeforeRule(new UnapproveBeforeRule());
}
}
8、保存校验:如果同一个人员下已经存在对应的非审批通过态的出库申请单,则提示“当前人员已经存在未生效的出库,不允许保存”
//新增保存校验是否存在未生效的出库
private void saveCheckNoeffectiveWarehousing(AggKfcksqdVO aggvo) throws BusinessException{
//获取前端的人员主键
String pk_psndoc = NullValueUtils.getNullStringValue(aggvo.getParentVO().getPersonnel());
//获取前端的主键
String pk_cksqd = NullValueUtils.getNullStringValue(aggvo.getParentVO().getPk_cksqd());
SqlBuilder sql = new SqlBuilder();
sql.append(" select billstatus ");
sql.append(" from kf_kfcksqd ");
sql.append(" where nvl(dr, 0) = 0 ");
sql.append(" and personnel = '" + pk_psndoc + "'");
sql.append(" and billstatus != 1 ");
//主键不为空,说明不是新增保存,是修改保存;当是修改保存时,返回主键不等于当前主键的单据号
//如果主键等于当前主键,返回的单据号为“”,可以跳过下面的if判断,即保存成功
if(!pk_cksqd.equals("")){
sql.append(" and pk_cksqd != '"+ pk_cksqd +"' ");
}
//获取数据库语句查询出来的单据状态
String billstatus = NullValueUtils.getNullStringValue(getDao().executeQuery(sql.toString(), new ColumnProcessor()));
if(!billstatus.equals("")){
throw new BusinessException("当前人员已经存在未生效的出库,不允许保存!!!");
}
}
//后端使用数据库查询要用到的方法
private BaseDAO dao;
private BaseDAO getDao() {
if(dao == null) {
dao = new BaseDAO();
}
return dao;
}
二、出库单
1、
表头字段:出库申请单号warehousingno(参照出库申请单) 、总数量sumnum
表体字段:客户customer(参照客户基本信息表)、数量num(数值型)、含税单价taxprice(数值型)、无税单价notaxprice(数值型不可编辑)、税率taxrate(数值型)、税额tax(数值型不可编辑)、无税金额notaxmny(数值型,不可编辑)、含税金额taxmny(数值型,不可编辑)
2、选择出库申请单号自动将出库申请单表体信息带到当前单据表体
package nc.ui.yhlypx.kfckd.ace.handler;
import java.util.List;
import nc.bs.framework.common.NCLocator;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.jdbc.framework.processor.BeanProcessor;
import nc.ui.pubapp.uif2app.event.IAppEventHandler;
import nc.ui.pubapp.uif2app.event.card.CardHeadTailAfterEditEvent;
import nc.ui.yhlypx.util.NullValueUtils;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.yhlypx.kfckd.KfckdBVO;
import nc.vo.yhlypx.kfckd.KfckdVO;
import nc.vo.yhlypx.kfcksqd.KfcksqdBVO;
/**
* 单据表头表尾字段编辑后事件处理类
*
* @since 6.0
* @version 2023-03-22
* @author hh
*/
public class AceHeadTailAfterEditHandler implements
IAppEventHandler<CardHeadTailAfterEditEvent> {
@Override
public void handleAppEvent(CardHeadTailAfterEditEvent e) {
//当前编辑字段的名称
String key=e.getKey();
try {
//判断当前编辑字段的名称是warehousingno出库申请单号
if(key.equals("warehousingno")){
//出库申请单号编辑后带出表体信息
warehousingnoBringoutXx(e);
}
} catch (BusinessException e1) {
ExceptionUtils.wrappBusinessException(e1.getMessage());
}
}
//出库申请单号编辑后带出表体信息
private void warehousingnoBringoutXx(CardHeadTailAfterEditEvent e) throws BusinessException{
//获取表头出库申请单号字段的值
String pk_cksqd = NullValueUtils.getNullStringValue(e.getBillCardPanel().getHeadItem("warehousingno").getValueObject());
//通过出库申请单号查询出库申请单表头信息
String sql = "select * from kf_kfcksqd where nvl(dr,0) = 0 and pk_cksqd ='" + pk_cksqd + "'";
//将数据库查到的该条记录赋值给headvo
KfckdVO headvo = (KfckdVO) getService().executeQuery(sql, new BeanProcessor(KfckdVO.class));
//如果表头合同号为空
if(headvo == null){
//清空表体字段的值
emptyXx(e);
}else{
//给出库单表头总数量字段赋值
e.getBillCardPanel().setHeadItem("sumnum", headvo.getSumnum());
//根据出库申请单号查询出库申请单表体信息
String strsql = "select * from kf_kfcksqd_b where nvl(dr,0) = 0 and pk_cksqd ='" + pk_cksqd + "'";
//将数据库查到的该集合赋值给list
List<KfcksqdBVO> list = (List<KfcksqdBVO>) getService().executeQuery(strsql, new BeanListProcessor(KfcksqdBVO.class));
//清空表体,目的是为了防止换选出库申请单号时表体数据累加
int rowCount = e.getBillCardPanel().getBillModel("id_kfckdbvo").getRowCount();
int[] rows = new int[rowCount];
for (int i = 0; i < rowCount; i++) {
rows[i] = i;
}
e.getBillCardPanel().getBillModel("id_kfckdbvo").delLine(rows);
if(list == null || list.size() <= 0){
return;
}
for (int i = 0; i < list.size(); i++) {
//查询出来的数据用出库申请单子表VO接收
KfcksqdBVO cksqdBVO = list.get(i);
//新建出库单子表VO
KfckdBVO ckdBVO = new KfckdBVO();
//给出库单子表客户赋值
ckdBVO.setCustomer(cksqdBVO.getCustomer());
//给出库单子表数量赋值
ckdBVO.setNum(cksqdBVO.getNum());
//给出库单子表含税单价赋值
ckdBVO.setTaxprice(cksqdBVO.getTaxprice());
//给出库单子表无税单价赋值
ckdBVO.setNotaxprice(cksqdBVO.getNotaxprice());
//给出库单子表税率赋值
ckdBVO.setTaxrate(cksqdBVO.getTaxrate());
//给出库单子表税额赋值
ckdBVO.setTax(cksqdBVO.getTax());
//给出库单子表无税金额赋值
ckdBVO.setNotaxmny(cksqdBVO.getNotaxmny());
//给出库单子表含税金额赋值
ckdBVO.setTaxmny(cksqdBVO.getTaxmny());
//给页签编码为id_yhlypxhtfkbvo增行
e.getBillCardPanel().getBillModel("id_kfckdbvo").addLine();
e.getBillCardPanel().getBillModel("id_kfckdbvo").setBodyRowVO(ckdBVO, i);
e.getBillCardPanel().getBillModel("id_kfckdbvo").setValueAt((i+1)*10+"", i, "rowno");
}
}
}
//清空表体字段的值
private void emptyXx(CardHeadTailAfterEditEvent e) throws BusinessException {
//给出库单表头总数量字段赋值
e.getBillCardPanel().setHeadItem("sumnum", null);
//清空表体
int rowCount = e.getBillCardPanel().getBillModel("id_kfckdbvo").getRowCount();
int[] rows = new int[rowCount];
for (int i = 0; i < rowCount; i++) {
rows[i] = i;
}
e.getBillCardPanel().getBillModel("id_kfckdbvo").delLine(rows);
}
//前端使用数据库查询语句必须增加的方法
private IUAPQueryBS service;
private IUAPQueryBS getService() {
if (service == null) {
service = NCLocator.getInstance().lookup(IUAPQueryBS.class);
}
return service;
}
}
3、只能参照到是否已出库为否的出库申请单
package nc.ui.yhlypx.kfckd.ace.handler;
import nc.ui.pub.beans.UIRefPane;
import nc.ui.pubapp.uif2app.event.IAppEventHandler;
import nc.ui.pubapp.uif2app.event.card.CardHeadTailBeforeEditEvent;
import nc.ui.yhlypx.util.NullValueUtils;
import nc.vo.pub.lang.UFBoolean;
/**
* 单据表头表尾字段编辑前事件处理类
*
* @since 6.0
* @version 2023-03-22
* @author hh
*/
public class AceHeadTailBeforeEditHandler implements IAppEventHandler<CardHeadTailBeforeEditEvent> {
@Override
public void handleAppEvent(CardHeadTailBeforeEditEvent e) {
String key = e.getKey();
if(key.equals("warehousingno")){
personnelfilter(e);
}
e.setReturnValue(UFBoolean.TRUE.booleanValue());
}
//只能参照到是否已出库为否的出库申请单
private void personnelfilter(CardHeadTailBeforeEditEvent e){
UIRefPane refPane = (UIRefPane) e.getBillCardPanel().getHeadItem("warehousingno").getComponent();
refPane.getRefModel().setWherePart("c.iswarehousing = 'N'");
}
}
4、表体不允许增行、插入行和删行
<!-- 表体行操作按钮注册,这只是一组默认设置,开发人员需要自己在此添加其他需要的表体行操作按钮 -->
<property name="bodyLineActions">
<list>
</list>
</property>
5、增加按钮:非编辑态下可用,联查出库明细,点击该按钮,自动弹框,将出库申请单明细进行弹框显示
列表下
<ref bean="TrainingPopoverAction" />
卡片下
<ref bean="TrainingPopoverAction" />
<!--弹窗按钮-->
<bean id="TrainingPopoverAction" class="nc.ui.yhlypx.kfckd.ace.action.TrainingPopoverAction">
<property name="model"><ref bean="bmModel"/></property>
<property name="editor"><ref bean="billForm"/></property>
</bean>
package nc.ui.yhlypx.kfckd.ace.action;
import java.awt.event.ActionEvent;
import nc.ui.pub.beans.UIDialog;
import nc.ui.yhlypx.kfckd.ace.dialog.PopupDialog;
import nc.ui.yhlypx.pub.baseaction.BaseAction;
import nc.vo.yhlypx.kfckd.AggKfckdVO;
import nc.vo.yhlypx.kfckd.KfckdBVO;
import nc.vo.yhlypx.kfckd.TrainingPopoverParam;
public class TrainingPopoverAction extends BaseAction<AggKfckdVO>{
private static final long serialVersionUID = -8740680740258059040L;
public TrainingPopoverAction(){
setCode("TrainingPopoverAction");
setBtnName("明细弹窗");
}
@Override
public void doAction(ActionEvent arg0) throws Exception {
TrainingPopoverParam param = new TrainingPopoverParam();
//获取选中AggVO
AggKfckdVO aggvo = getSelectedAggVo();//非编辑态下获取AggVo的方法
KfckdBVO[] bvos = (KfckdBVO[]) aggvo.getChildren(KfckdBVO.class);
param.setBvos(bvos);
PopupDialog dialog = new PopupDialog(param);
if(dialog.showModal() != UIDialog.ID_OK){
return;
}
}
@Override
protected boolean isActionEnable() {
// TODO 自动生成的方法存根
if(getModel().getSelectedOperaDatas()==null){
return false;
}
return true;
}
}
package nc.ui.yhlypx.kfckd.ace.dialog;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.util.List;
import nc.ui.pub.beans.MessageDialog;
import nc.ui.pub.beans.UIButton;
import nc.ui.pub.beans.UIDialog;
import nc.ui.pub.beans.UIPanel;
import nc.ui.pub.bill.BillCardPanel;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.AppContext;
import nc.vo.yhlypx.kfckd.TrainingPopoverParam;
/**
* 弹窗按钮弹出对话框
*
* @author:hh
* @date :2023-3-8
*/
public class PopupDialog extends UIDialog {
private static final long serialVersionUID = 8569366112349546821L;
private UIPanel UIPanel = null;
private BillCardPanel billCardPanel = null; // 获取到在NC里面对应的单据模板,不用自己画模板
private UIPanel UIPanel3 = null;
private UIButton okBtn;
private TrainingPopoverParam param;
@SuppressWarnings("deprecation")
public PopupDialog(TrainingPopoverParam param) {
init(param); // 设置窗体大小
}
public void init(TrainingPopoverParam param) {
this.setContentPane(getUIPanel());
this.setTitle("明细弹窗");
this.setSize(600, 300);
getBillCardPanel().getBillModel().setBodyDataVO(param.getBvos());
}
private UIPanel getUIPanel() {
if (UIPanel == null) {
UIPanel = new UIPanel();
UIPanel.setLayout(new BorderLayout());
UIPanel.add(getBillCardPanel(), java.awt.BorderLayout.CENTER);
UIPanel.add(getUIPanel3(), java.awt.BorderLayout.SOUTH);
}
return UIPanel;
}
private BillCardPanel getBillCardPanel() {
if (billCardPanel == null) {
billCardPanel = new BillCardPanel();
billCardPanel.loadTemplet("px", null, AppContext.getInstance().getPkUser(), null);
}
return billCardPanel;
}
private UIPanel getUIPanel3() {
if (UIPanel3 == null) {
initUIButtons();
UIPanel3 = new UIPanel();
UIPanel UIPanel4 = new UIPanel();
UIPanel4.setLayout(new FlowLayout());
UIPanel4.add(okBtn);
UIPanel3.add(UIPanel4, null);
}
return UIPanel3;
}
private void initUIButtons() {
okBtn = new UIButton("确定");
okBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
try {
getBillCardPanel().dataNotNullValidate();
} catch (BusinessException e1) {
// TODO 自动生成的 catch 块
MessageDialog.showErrorDlg(getBillCardPanel(), "错误", e1.getMessage());
return;
}
closeOK();
}
});
}
}
6、出库申请单参照字段(单据号、单据日期、人员、部门、总数量)
package nc.ui.yhlypx.pub.ref;
import nc.ui.bd.ref.AbstractRefModel;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
/**
* 出库申请单参照
*
* @author hh
*/
public class KfcksqdRef extends AbstractRefModel {
public int getDefaultFieldCount() {
return 7;
}
/**
* 参照数据库字段名数组
*
* @return java.lang.String
*/
public java.lang.String[] getFieldCode() {
return new String[] { "c.vbillno", "dbilldate", "personnelname", "departmentname",
"c.sumnum", "c.pk_cksqd", "c.iswarehousing"};
}
public String getRefNameField() {
return "c.vbillno";
}
@Override
public String getRefCodeField() {
// TODO 自动生成的方法存根
return "c.vbillno";
}
/**
* 和数据库字段名数组对应的中文名称数组
*
* @return java.lang.String
*/
public java.lang.String[] getFieldName() {
return new String[] { "单据号", "单据日期", "人员", "部门", "总数量", "主键", "是否已出库"};
}
// 默认不显示字段
public java.lang.String[] getHiddenFieldCode() {
return new String[] { "c.pk_cksqd","c.iswarehousing" };
}
/**
* 要返回的主键字段名
*
* @return java.lang.String
*/
public String getPkFieldCode() {
return "c.pk_cksqd";
}
/**
* 参照标题
*
* @return java.lang.String
*/
public String getRefTitle() {
return "出库申请单";
}
/**
* 参照数据库表或者视图名
*
* @return java.lang.String
*/
public String getTableName() {
SqlBuilder sqlBuilder = new SqlBuilder();
sqlBuilder.append("( ");
sqlBuilder.append(" select c.vbillno,");
sqlBuilder.append(" substr(c.dbilldate, 1, 10) dbilldate,");
sqlBuilder.append(" p.name personnelname,");
sqlBuilder.append(" d.name departmentname,");
sqlBuilder.append(" c.sumnum,");
sqlBuilder.append(" c.pk_cksqd,");
sqlBuilder.append(" c.iswarehousing");
sqlBuilder.append(" from kf_kfcksqd c");
sqlBuilder.append(" left join bd_psndoc p");
sqlBuilder.append(" on c.personnel = p.pk_psndoc");
sqlBuilder.append(" left join org_dept d");
sqlBuilder.append(" on c.department = d.pk_dept");
sqlBuilder.append(" where nvl(c.dr,0) = 0");
sqlBuilder.append(" ) c ");
return sqlBuilder.toString();
}
@Override
public boolean isCacheEnabled() {
return false;
}
}
7、选择出库申请单号自动将出库申请单号表头总数量带到出库单表头总数量中
第二问中已实现
8、保存校验:表体数量合计是否等于表头总数量,如果不等则提示“表体数量合计不等于表头”
/新增保存校验表体数量合计是否等于表头总数量
private void saveCheckSumsum(AggKfckdVO aggvo) throws BusinessException{
//通过aggvo获取表体
KfckdBVO[] bvos = (KfckdBVO[]) aggvo.getChildren(KfckdBVO.class);
//[]这种情况不为空,但是不能进入循环,所以还要加上bvos.length > 0这个条件
if(bvos != null && bvos.length > 0){
//定义一个求和变量,初始化为0
UFDouble sum = UFDouble.ZERO_DBL;;
//遍历表体
for (int i = 0; i < bvos.length; i++) {
//累加数量
sum = sum.add(NullValueUtils.getNullUFdoubleValue(bvos[i].getNum()));
}
if(!sum.equals(aggvo.getParentVO().getSumnum())){
throw new BusinessException(" 表体数量合计不等于表头总数量!!! ");
}
}
}
9、保存校验:一张出库申请单只能生成一张出库单
//保存校验一个出库申请单只能被参照一次
private void saveCheckReference(AggKfckdVO aggvo) throws BusinessException{
//获取前端的出库申请单号
String pk_cksqd = NullValueUtils.getNullStringValue(aggvo.getParentVO().getWarehousingno());
//获取前端的主键
String pk_ckd = NullValueUtils.getNullStringValue(aggvo.getParentVO().getPk_ckd());
SqlBuilder sql = new SqlBuilder();
sql.append(" select vbillno ");
sql.append(" from kf_kfckd ");
sql.append(" where nvl(dr, 0) = 0 ");
sql.append(" and warehousingno = '"+ pk_cksqd +"' ");
//主键不为空,说明不是新增保存,是修改保存;当是修改保存时,返回主键不等于当前主键的单据号
//如果主键等于当前主键,返回的单据号为"",可以跳过下面的if判断,即保存成功
if(!pk_ckd.equals("")){
sql.append(" and pk_ckd != '"+ pk_ckd +"' ");
}
//获取数据库语句查询出来的单据号
String vbillno = NullValueUtils.getNullStringValue(getDao().executeQuery(sql.toString(), new ColumnProcessor()));
//单据号不为空,说明该贷款合同的合同编号已被该放款单参照过
if(!vbillno.equals("")){
throw new BusinessException(" 保存失败:当前出库申请号已被单据号为:"+ vbillno +"出库单引用,请重新选择出库申请单号!!! ");
}
}
//后端使用数据库查询要用到的方法
private BaseDAO dao;
private BaseDAO getDao() {
if(dao == null) {
dao = new BaseDAO();
}
return dao;
}
10、出库单审批回写出库申请单是否已出库字段
package nc.bs.yhlypx.kfckd.ace.bp.rule.approve;
import nc.bs.framework.common.NCLocator;
import nc.impl.pubapp.pattern.data.bill.BillQuery;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.itf.yhlypx.IKfcksqdMaintain;
import nc.ui.yhlypx.util.NullValueUtils;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.yhlypx.kfckd.AggKfckdVO;
import nc.vo.yhlypx.kfcksqd.AggKfcksqdVO;
public class ApproveAfterWriteBackRule implements IRule<AggKfckdVO>{
@Override
public void process(AggKfckdVO[] aggvos) {
for(int i = 0; i < aggvos.length; i++){
try {
//出库单审批回写出库申请单是否已出库字段
ApproveAfterWrite(aggvos[i]);
} catch (BusinessException e) {
ExceptionUtils.wrappBusinessException(e.getMessage());
}
}
}
//出库单审批回写出库申请单是否已出库字段
private void ApproveAfterWrite(AggKfckdVO aggvo) throws BusinessException{
//通过出库申请单号获取主表主键
String pk_cksqd = NullValueUtils.getNullStringValue(aggvo.getParentVO().getWarehousingno());
//判断出库申请单主表主键是否为空
if(!pk_cksqd.equals("")){
//创建billQuery查询出库申请单对象
BillQuery<AggKfcksqdVO> billQuery = new BillQuery<AggKfcksqdVO> (AggKfcksqdVO.class);
//根据出库申请单主表主键查询出库申请单aggvos
AggKfcksqdVO[] aggvos = billQuery.query(new String[] { pk_cksqd });
//克隆aggvo
AggKfcksqdVO clonevo = (AggKfcksqdVO) aggvos[0].clone();
//获取出库单单据状态
String billstatus = aggvo.getParentVO().getBillstatus().toString();
//如果出库单单据状态字段的值为1
if(billstatus.equals("1")){
//给出库申请单主表的是否已出库字段赋值为TRUE
clonevo.getParentVO().setIswarehousing(UFBoolean.TRUE);
//将出库申请单主表的VOStatus的状态赋值为更新态
clonevo.getParentVO().setStatus(VOStatus.UPDATED);
}
//调用合同修改接口
getService().update(new AggKfcksqdVO[]{clonevo}, aggvos);
}
}
//要修改哪个单子调哪个单子的接口
private IKfcksqdMaintain service;
private IKfcksqdMaintain getService() {
if (service == null) {
service = NCLocator.getInstance().lookup(IKfcksqdMaintain.class);
}
return service;
}
}
package nc.bs.yhlypx.kfckd.ace.bp;
import nc.bs.yhlypx.kfckd.ace.bp.rule.approve.ApproveAfterWriteBackRule;
import nc.bs.yhlypx.kfckd.plugin.bpplugin.KfckdPluginPoint;
import nc.impl.pubapp.pattern.data.bill.template.UpdateBPTemplate;
import nc.impl.pubapp.pattern.rule.processer.CompareAroundProcesser;
import nc.vo.pub.VOStatus;
import nc.vo.yhlypx.kfckd.AggKfckdVO;
/**
* 标准单据审核的BP
*/
public class AceKfckdApproveBP {
/**
* 审核动作
*
* @param vos
* @param script
* @return
*/
public AggKfckdVO[] approve(AggKfckdVO[] clientBills,
AggKfckdVO[] originBills) {
for (AggKfckdVO clientBill : clientBills) {
clientBill.getParentVO().setStatus(VOStatus.UPDATED);
}
UpdateBPTemplate<AggKfckdVO> bp = new UpdateBPTemplate<AggKfckdVO>(KfckdPluginPoint.UPDATE);
this.addAfterRule(bp.getAroundProcesser());
AggKfckdVO[] returnVos = bp.update(clientBills, originBills);
return returnVos;
}
private void addAfterRule(CompareAroundProcesser<AggKfckdVO> compareAroundProcesser) {
// 出库单审批后回写出库申请单
compareAroundProcesser.addAfterRule(new ApproveAfterWriteBackRule());
}
}
11、出库单取消审批回写出库申请单是否已出库字段
package nc.bs.yhlypx.kfckd.ace.bp.rule.unapprove;
import nc.bs.framework.common.NCLocator;
import nc.impl.pubapp.pattern.data.bill.BillQuery;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.itf.yhlypx.IKfcksqdMaintain;
import nc.ui.yhlypx.util.NullValueUtils;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.yhlypx.kfckd.AggKfckdVO;
import nc.vo.yhlypx.kfcksqd.AggKfcksqdVO;
public class UnapproveAfterWriteBackRule implements IRule<AggKfckdVO>{
@Override
public void process(AggKfckdVO[] aggvos) {
for(int i = 0; i < aggvos.length; i++){
try {
//出库单取消审批回写出库申请单是否已出库字段
UnapproveAfterWrite(aggvos[i]);
} catch (BusinessException e) {
ExceptionUtils.wrappBusinessException(e.getMessage());
}
}
}
private void UnapproveAfterWrite(AggKfckdVO aggvo) throws BusinessException{
//通过出库申请单号获取主表主键
String pk_cksqd = NullValueUtils.getNullStringValue(aggvo.getParentVO().getWarehousingno());
//判断出库申请单主表主键是否为空
if(!pk_cksqd.equals("")){
//创建billQuery查询出库申请单对象
BillQuery<AggKfcksqdVO> billQuery = new BillQuery<AggKfcksqdVO> (AggKfcksqdVO.class);
//根据出库申请单主表主键查询出库申请单aggvos
AggKfcksqdVO[] aggvos = billQuery.query(new String[] { pk_cksqd });
//克隆aggvo
AggKfcksqdVO clonevo = (AggKfcksqdVO) aggvos[0].clone();
//获取出库单单据状态
String billstatus = aggvo.getParentVO().getBillstatus().toString();
//如果出库单单据状态字段的值为1
if(billstatus.equals("-1")){
//给出库申请单主表的是否已出库字段赋值为TRUE
clonevo.getParentVO().setIswarehousing(UFBoolean.FALSE);
//将出库申请单主表的VOStatus的状态赋值为更新态
clonevo.getParentVO().setStatus(VOStatus.UPDATED);
}
//调用合同修改接口
getService().update(new AggKfcksqdVO[]{clonevo}, aggvos);
}
}
//要修改哪个单子调哪个单子的接口
private IKfcksqdMaintain service;
private IKfcksqdMaintain getService() {
if (service == null) {
service = NCLocator.getInstance().lookup(IKfcksqdMaintain.class);
}
return service;
}
}
package nc.bs.yhlypx.kfckd.ace.bp;
import nc.bs.yhlypx.kfckd.ace.bp.rule.unapprove.UnapproveAfterWriteBackRule;
import nc.bs.yhlypx.kfckd.plugin.bpplugin.KfckdPluginPoint;
import nc.impl.pubapp.pattern.data.bill.template.UpdateBPTemplate;
import nc.impl.pubapp.pattern.rule.processer.CompareAroundProcesser;
import nc.vo.pub.VOStatus;
import nc.vo.yhlypx.kfckd.AggKfckdVO;
/**
* 标准单据弃审的BP
*/
public class AceKfckdUnApproveBP {
public AggKfckdVO[] unApprove(AggKfckdVO[] clientBills,
AggKfckdVO[] originBills) {
for (AggKfckdVO clientBill : clientBills) {
clientBill.getParentVO().setStatus(VOStatus.UPDATED);
}
UpdateBPTemplate<AggKfckdVO> bp = new UpdateBPTemplate<AggKfckdVO>(KfckdPluginPoint.UPDATE);
this.addAfterRule(bp.getAroundProcesser());
AggKfckdVO[] returnVos = bp.update(clientBills, originBills);
return returnVos;
}
private void addAfterRule(CompareAroundProcesser<AggKfckdVO> compareAroundProcesser) {
// 出库单审批后回写出库申请单
compareAroundProcesser.addAfterRule(new UnapproveAfterWriteBackRule());
}
}