Commit 76c0843e sunke

同一个PN允许多个供应商

条码数量如果与上次不一致(重打标签,用同一个RI),使用条码中的数量
1 个父辈 133b5c2e
正在显示 22 个修改的文件 包含 207 行增加70 行删除
......@@ -1455,6 +1455,21 @@ public class CsvReader {
}
}
public int getIndex(String... headerNameAlias){
for (String headName: headerNameAlias) {
try{
int index = getIndex(headName);
if(index != -1){
return index;
}
}catch (Exception e){
}
}
return -1;
}
/**
* Skips the next record of data by parsing each column. Does not
* increment
......
......@@ -55,6 +55,10 @@ public class Barcode extends BaseMongoBean {
private String providerNumber;
private int initialAmount;
private int amount;
/**
* 标签解析出来的数量,用于判断条码是否是重新打印的,重新打印的条码需要重新设置数量
*/
private int labelAmount = 0;
private int plateSize;
private int height;
private String provider;
......@@ -638,6 +642,14 @@ public class Barcode extends BaseMongoBean {
return false;
}
public int getLabelAmount() {
return labelAmount;
}
public void setLabelAmount(int labelAmount) {
this.labelAmount = labelAmount;
}
// public void setNoChangeField(Barcode oldBarcode){
// if(oldBarcode != null){
// this.expireDate = oldBarcode.getExpireDate();
......
......@@ -9,7 +9,9 @@ import java.util.List;
*/
public interface IComponentManager extends IManager<Component> {
public Component findByPartNumber(String partNumber);
public Component findOneByPN(String partNumber);
Component findByPartNumberAndProvider(String partNumber, String provider);
List<Component> allNeedAlarmComponents();
......
......@@ -57,8 +57,38 @@ public class BarcodeManagerImpl implements IBarcodeManager {
@Override
public Barcode save(Barcode barcode) throws ValidateException{
validateSave(barcode);
Component component = componentManager.findByPartNumber(barcode.getPartNumber());
Component component = componentManager.findByPartNumberAndProvider(barcode.getPartNumber(), barcode.getProvider());
if(component == null){
//未找到对应供应商的物料,如果有无供应商的物料,更改并使用
log.info("找到供应商信息为空的档案,修改档案的供应商信息"+barcode.getProvider());
component = componentManager.findByPartNumberAndProvider(barcode.getPartNumber(), null);
}
if(component == null){
//查找其他供应商的物料档案,复制一个
component = componentManager.findOneByPN(barcode.getPartNumber());
if(component != null){
log.info("未找到["+barcode.getPartNumber()+"]供应商["+barcode.getProvider()+"]对应的档案信息,从其他供应商["+component.getProvider()+"]档案复制一个");
//找到了,复制一个
Component newComponent = new Component();
newComponent.setProvider(barcode.getProvider());
newComponent.setPlateSize(component.getPlateSize());
newComponent.setHeight(component.getHeight());
newComponent.setPartNumber(component.getPartNumber());
newComponent.setAmount(barcode.getAmount());
newComponent.setName(component.getPartNumber());
component = componentManager.save(component);
}
}
if(component != null){
if(Strings.isNullOrEmpty(component.getProvider())){
//无供应商信息,更新供应商信息
log.info("设置["+component.getPartNumber()+"]的供应商信息:"+ barcode.getProvider());
component.setProvider(barcode.getProvider());
componentManager.save(component);
}
if(barcode.getMaxStorageTime() <= 0){
barcode.setMaxStorageTime(component.getMaxStorageTime());
}
......@@ -77,11 +107,6 @@ public class BarcodeManagerImpl implements IBarcodeManager {
}else{
log.error("未找到物料["+barcode.getPartNumber()+"]的档案");
}
// String id = barcode.getId();
// if(!Strings.isNullOrEmpty(id)){
// Barcode oldBarcode = get(id);
// //barcode.setNoChangeField(oldBarcode);
// }
return barcodeDao.save(barcode);
}
......@@ -120,7 +145,7 @@ public class BarcodeManagerImpl implements IBarcodeManager {
protected boolean validateComponent(Barcode barcode) {
return componentManager.findByPartNumber(barcode.getPartNumber()) != null;
return componentManager.findOneByPN(barcode.getPartNumber()) != null;
}
protected boolean validateUnique(Barcode barcode) {
......
......@@ -33,13 +33,30 @@ public class ComponentManagerImpl implements IComponentManager {
}
@Override
public Component findByPartNumber(String partNumber) {
public Component findOneByPN(String partNumber) {
if (StringUtils.isEmpty(partNumber))
return null;
else return componentDao.findOneByCondition(new String[] {"partNumber"}, new String[] {partNumber});
}
@Override
public Component findByPartNumberAndProvider(String partNumber, String provider) {
if (StringUtils.isEmpty(partNumber))
return null;
else {
Component component = componentDao.findOneByCondition(new String[] {"partNumber","provider"}, new String[] {partNumber,provider});
if(component == null){
component = componentDao.findOneByCondition(new String[] {"partNumber","provider"}, new String[] {partNumber,null});
if(provider == null && component == null){
//再查一下空字符串的
component = componentDao.findOneByCondition(new String[] {"partNumber","provider"}, new String[] {partNumber, ""});
}
}
return component;
}
}
@Override
public List<Component> allNeedAlarmComponents(){
Criteria c = Criteria.where("minStoreNum").gt(0);
Query query = Query.query(c);
......@@ -76,7 +93,7 @@ public class ComponentManagerImpl implements IComponentManager {
public Component save(Component component) throws ValidateException{
String partNumber = component.getPartNumber();
Component dbComponent = findByPartNumber(partNumber);
Component dbComponent = findByPartNumberAndProvider(partNumber, component.getProvider());
if(dbComponent != null){
//数据库中已存在,但不是更新(要保存的没有 ID,或者有 ID但与数据库中的 ID不一致)
if(Strings.isNullOrEmpty(component.getId()) || !dbComponent.getId().equals(component.getId()) ){
......
......@@ -177,7 +177,7 @@ public class TcpServer {
barcode.setAmount(amount);
//未补过料
if(Strings.isNullOrEmpty(barcode.getNextBarcode())){
Component component = componentManager.findByPartNumber(barcode.getPartNumber());
Component component = componentManager.findOneByPN(barcode.getPartNumber());
int alarmAmount = component.getAlarmAmount();
if(amount <= alarmAmount){
StoragePos pos = storagePosManager.findPartNumberPos(null,barcode.getPartNumber(),new ArrayList<String>(), StorageConstants.CHECKOUT_TYPE.FIFO);
......
......@@ -644,7 +644,7 @@ public class BarcodeRule {
//rule = "SP;PN;PRODATEyyyyMMdd[0:8:0];BATCH;QTY;RI;";
codeStr = "=7x8=[)>@SIIX20@2060GBUW00@1347-01358@5000.000 @@";
rule = "1@[RI]@BATCH@PN@QTY@@";
rule = "1@RI@BATCH@PN@QTY@@";
BarcodeRule br = BarcodeRule.newRule(rule);
Barcode b = br.toCodeBean(codeStr).getBarcode();
......
......@@ -65,7 +65,7 @@ public class BarcodeGenerateController extends BaseUpdateController {
barcode.setStatus(StorageConstants.BARCODE_STATUS.NEW);
barcode.setUsed(false);
//String componentId = barcode.getComponentId();
Component component = componentManager.findByPartNumber(barcode.getPartNumber());
Component component = componentManager.findOneByPN(barcode.getPartNumber());
if(StringUtils.isEmpty(barcode.getBarcode())) {
String bs = getUuid();
......
......@@ -282,7 +282,7 @@ public class BoxChartController extends BaseController {
List<SolderInventoryItem> results = Lists.newArrayList();
for (InventoryItem inventoryItem : storageTypeInventory.values()) {
String partNumber = inventoryItem.getPartNumber();
Component component = componentManager.findByPartNumber(partNumber);
Component component = componentManager.findOneByPN(partNumber);
int minStoreNum = component.getMinStoreNum();
int maxStoreNum = component.getMaxStoreNum();
......
......@@ -284,7 +284,7 @@ public class SmdXLController extends BaseController{
if(opType != StorageConstants.OP.NON_OP){
//手动输入,按PN来处理
//先查找是否有相同的PN,没有创建一个
Component component = componentManager.findByPartNumber(pnStr);
Component component = componentManager.findOneByPN(pnStr);
if(component == null){
component = new Component();
component.setHeight(1);
......
......@@ -227,7 +227,7 @@ public class VerticalBoxController extends BaseController{
String pnStr = codeArray[0];
int opQty = Integer.valueOf(codeArray[1]);
//先查找是否有相同的PN,没有创建一个
Component component = componentManager.findByPartNumber(pnStr);
Component component = componentManager.findOneByPN(pnStr);
if(component == null){
component = new Component();
component.setHeight(1);
......
......@@ -228,8 +228,8 @@ public class DataCache{
codeBeanFromRule.setError(null,null);
codeBeanFromRule.setCodeStr(barcode.getBarcode());
codeBeanFromRule.setBarcode(barcode);
Component component = componentManager.findByPartNumber(barcode.getPartNumber());
codeBeanFromRule.setShowImg(component.getShowImg());
// Component component = componentManager.findByPartNumber(barcode.getPartNumber());
// codeBeanFromRule.setShowImg(component.getShowImg());
return codeBeanFromRule;
}
......@@ -256,7 +256,7 @@ public class DataCache{
}
}
}
Component component = componentManager.findByPartNumber(barcode.getPartNumber());
Component component = componentManager.findByPartNumberAndProvider(barcode.getPartNumber(),barcode.getProvider());
int validDay = 0;
if(component != null){
validDay = component.getValidDay();
......@@ -265,22 +265,36 @@ public class DataCache{
Barcode barcodeFromRule = codeBeanFromRule.getBarcode();
if(barcodeFromRule != null){
boolean needUpdate = false;
int lastLabelAmount = barcode.getLabelAmount();
int currentLabelAmount = barcodeFromRule.getAmount();
if(currentLabelAmount != lastLabelAmount){
//本次解析出来的数量与上次条码解析出来的数量不一样,重新设置数量
log.info("重新设置"+codeBeanFromRule.getCodeStr()+"数量为:"+currentLabelAmount);
barcode.setAmount(currentLabelAmount);
barcode.setLabelAmount(currentLabelAmount);
needUpdate = true;
}
Date produceDate = barcodeFromRule.getProduceDate();
if(produceDate != null){
//抓取到了生产日期,未抓取到过期日期,重新设置过期日期
if(barcode.getExpireDate() == null){
if(validDay > 0){
try {
log.warn("重新设置"+codeBeanFromRule.getCodeStr()+"生产日期和过期日期");
log.info("重新设置"+codeBeanFromRule.getCodeStr()+"生产日期和过期日期");
Date expireDate = DateUtil.addDays(produceDate, validDay);
barcode.setExpireDate(expireDate);
barcode.setProduceDate(produceDate);
barcodeManager.save(barcode);
}catch (Exception e){
needUpdate = true;
}
}
}
if(needUpdate){
try {
barcodeManager.save(barcode);
}catch (Exception e){
log.error(e);
}
}
}
......@@ -294,7 +308,7 @@ public class DataCache{
//如果有料盘尺寸,重新设置料盘尺寸信息,没有档案时自动添加档案
if(codeBeanFromRule.hasReelSizeInfo()){
//log.info("料盘["+barcode.getBarcode()+"]的尺寸信息从["+barcode.getPlateSize()+"x"+barcode.getHeight()+"]设置为["+codeBeanFromRule.getReelWidth()+"x"+codeBeanFromRule.getReelHeight()+"]");
Component component = componentManager.findByPartNumber(barcodeFromRule.getPartNumber());
Component component = componentManager.findByPartNumberAndProvider(barcodeFromRule.getPartNumber(),barcodeFromRule.getProvider());
if(component == null){
log.info("自动添加["+barcodeFromRule.getPartNumber()+"]的档案信息["+codeBeanFromRule.getReelWidth()+"x"+codeBeanFromRule.getReelHeight()+"]");
......@@ -329,7 +343,7 @@ public class DataCache{
}
if(needAddNew){
log.info("自动添加条码"+barcodeItemStr+"到数据库中");
Component component = componentManager.findByPartNumber(barcodeFromRule.getPartNumber());
Component component = componentManager.findByPartNumberAndProvider(barcodeFromRule.getPartNumber(),barcodeFromRule.getProvider());
if(component == null){
log.info("档案["+barcodeFromRule.getPartNumber()+"]不存在");
throw new ValidateException("component.error.notExist",new String[]{barcodeFromRule.getPartNumber()});
......@@ -376,18 +390,18 @@ public class DataCache{
}
public Collection<CodeBean> resolveCodeStr(String codeStr){
Map<String, CodeBean> codeBeanMap = Maps.newHashMap();
List<CodeBean> codeBeans = Lists.newArrayList();
//Map<String, CodeBean> codeBeanMap = Maps.newHashMap();
if(!Strings.isNullOrEmpty(codeStr)){
//双##号分割多个二维码
String[] barcodeItemStrs = codeStr.split("##");
//需要检查partNumber 是否一致
Multiset<String> partNumberMultiset = HashMultiset.create();
//Multiset<String> partNumberMultiset = HashMultiset.create();
//含有最多的 partNumber
String mostPartNumber = "";
//String mostPartNumber = "";
List<CodeBean> codeBeans = Lists.newArrayList();
for (String barcodeItemStr : barcodeItemStrs){
CodeBean codeBean = resolveSingleCode(barcodeItemStr);
if(codeBean == null){
......@@ -395,26 +409,59 @@ public class DataCache{
}
codeBeans.add(codeBean);
//统计非夹具的 partNubmer
if(codeBean.isValid() && !codeBean.isFixtureCode()){
String partNumber = codeBean.getBarcode().getPartNumber();
partNumberMultiset.add(partNumber);
if(partNumberMultiset.count(partNumber) > partNumberMultiset.count(mostPartNumber) ){
mostPartNumber = partNumber;
// if(codeBean.isValid() && !codeBean.isFixtureCode()){
// String partNumber = codeBean.getBarcode().getPartNumber();
// partNumberMultiset.add(partNumber);
// if(partNumberMultiset.count(partNumber) > partNumberMultiset.count(mostPartNumber) ){
// mostPartNumber = partNumber;
// }
// }
}
// for (CodeBean codeBean : codeBeans) {
// if(codeBean.isValid() && !codeBean.isFixtureCode()){
// //非夹具的 partNumber 不一致
// if(!mostPartNumber.equals(codeBean.getBarcode().getPartNumber())){
// codeBean.setError("error.barcode.wrongPn", "PartNumber不一致");
// }
// }
// codeBeanMap.put(codeBean.getCodeStr(), codeBean);
// }
}
//return codeBeanMap.values();
return codeBeans;
}
/**
* 从条码信息中解析出一个有效条码
* @param codeStr
* @return
*/
public Barcode resolveOneValideBarcode(String codeStr) throws ValidateException{
if(org.apache.logging.log4j.util.Strings.isBlank(codeStr)){
throw new ValidateException("error.barcode.empty","未扫到条码");
}
Collection<CodeBean> codeBeans = resolveCodeStr(codeStr);
Barcode barcode = null;
String errorMsg = "";
for (CodeBean codeBean : codeBeans) {
if(codeBean.isValid() && !codeBean.isFixtureCode()){
//非夹具的 partNumber 不一致
if(!mostPartNumber.equals(codeBean.getBarcode().getPartNumber())){
codeBean.setError("error.barcode.wrongPn", "PartNumber不一致");
if(codeBean.isValid()){
Barcode barcodeFromRule = codeBean.getBarcode();
if(barcode == null){
barcode = barcodeFromRule;
}else{
throw new ValidateException("error.barcode.many",new String[]{codeStr},"找到多个有效的条码");
}
}else{
errorMsg = codeBean.getError();
}
codeBeanMap.put(codeBean.getCodeStr(), codeBean);
}
if(barcode == null){
throw new ValidateException("error.barcode.invalid",new String[]{codeStr}, "无效的条码");
}
return codeBeanMap.values();
return barcode;
}
/**
......
......@@ -72,7 +72,7 @@ public class MesApiController extends BaseController {
log.info("收到 MES 的 数据同步信息"+Partnumber+"【"+w+"x"+h+"】");
Component c = componentManager.findByPartNumber(Partnumber);
Component c = componentManager.findOneByPN(Partnumber);
if(c == null){
c = new Component();
}
......@@ -130,7 +130,7 @@ public class MesApiController extends BaseController {
String PARTNUMBER = checkParameter(request,"PN");
String QTY = checkParameter(request,"QTY");
log.info("收到条码同步信息:RI="+REEL_ID + " PN=" + PARTNUMBER + " QTY="+QTY);
Component c = componentManager.findByPartNumber(PARTNUMBER);
Component c = componentManager.findOneByPN(PARTNUMBER);
if(c == null){
return "Error: 物料编号[" + PARTNUMBER + "]的档案不存在";
}
......
......@@ -622,6 +622,7 @@ public class StorageDataController extends BaseController {
String code = request.getParameter("code");
String cids = request.getParameter("cids");
lineMsgParams = null;
log.info("["+cids+"]获取["+code+"]的入库库位");
Map<String,Object> resultMap = Maps.newHashMap();
if(Strings.isNullOrEmpty(cids)){
resultMap.put("result","101");
......@@ -640,23 +641,9 @@ public class StorageDataController extends BaseController {
String msg = getText(lineMsgParams.getMessage(),lineMsgParams.getParams(), request.getLocale(),lineMsgParams.getDefaultMsg());
resultMap.put("msg",msg);
}else{
Collection<CodeBean> codeBeans = dataCache.resolveCodeStr(code);
Barcode barcode = null;
for (CodeBean codeBean: codeBeans) {
if(codeBean.isValid()){
barcode = codeBean.getBarcode();
break;
}
}
if(barcode == null){
resultMap.put("result","103");
lineMsgParams = new ValidateException("error.barcode.invalid",new String[]{code}, "无效的条码");
String msg = getText(lineMsgParams.getMessage(),lineMsgParams.getParams(), request.getLocale(),lineMsgParams.getDefaultMsg());
resultMap.put("msg",msg);
}else {
StoragePos pos = null;
try {
pos = taskService.findEmptyPosForPutIn(storageList,barcode);
Barcode barcode = dataCache.resolveOneValideBarcode(code);
StoragePos pos = taskService.findEmptyPosForPutIn(storageList,barcode);
if(pos != null){
resultMap.put("result","0");
resultMap.put("msg","");
......@@ -681,7 +668,6 @@ public class StorageDataController extends BaseController {
}
}
}
}
return resultMap;
}
......
......@@ -185,7 +185,7 @@ public class TaskService implements ITaskService {
* @return
*/
private Barcode updateToSolderBarcode(Barcode barcode, int weight) throws ValidateException {
Component component = componentManager.findByPartNumber(barcode.getPartNumber());
Component component = componentManager.findOneByPN(barcode.getPartNumber());
if(!component.isSolder()){
component.setType(StorageConstants.COMPONENT_TYPE.SOLDERPASTE);
//搅拌时间默认为3分钟即180秒
......@@ -1702,6 +1702,8 @@ public class TaskService implements ITaskService {
task.setOperator(opUser);
task.setBatchInfo(barcode.getBatch());
task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
task = dataLogDao.save(task);
......@@ -1842,7 +1844,7 @@ public class TaskService implements ITaskService {
if(Strings.isNullOrEmpty(url)){
return false;
}
log.info("向 MES 通知【"+reelBarcode+"】的入库信息");
log.info("向 MES("+url+") 通知【"+reelBarcode+"】的入库信息");
Barcode barcode = barcodeManager.findByBarcode(reelBarcode);
Map<String, Object> params = new HashMap<String, Object>();
params.put("RI",reelBarcode);
......
......@@ -415,3 +415,4 @@ storage.chart.temperature=\u6E29\u5EA6
error.barcode.wrongProduceDate=\u751F\u4EA7\u65E5\u671F\u89E3\u6790\u5931\u8D25
shelf.error.orderError=\u4EFB\u52A1\u4E0E\u6307\u5B9A\u5DE5\u5355[{0}]\u4E0D\u4E00\u81F4
workOrder.supplementary=\u8865\u6599
error.barcode.manyvalid=[{0}]\u627E\u5230\u591A\u4E2A\u6709\u6548\u6761\u7801
mongo.replica-set=10.60.17.19:20000,10.60.17.20:20000,10.60.17.21:20000
mongo.replica-set=localhost:27017,192.168.1.107:27017,192.168.1.245:27017,192.168.1.116:27017
mongo.connectionsPerHost=8
mongo.threadsAllowedToBlockForConnectionMultiplier=4
mongo.connectTimeout=10000
......
......@@ -11,9 +11,9 @@
">
<context:property-placeholder location="classpath*:/*.properties" />
<!--
<mongo:mongo id="mongo" replica-set="${mongo.replica-set}">
-->
<!--<mongo:mongo id="mongo" replica-set="${mongo.replica-set}">-->
<mongo:mongo id="mongo" host="${mongo.host}" port="27017">
<mongo:options connections-per-host="${mongo.connectionsPerHost}"
threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
......
......@@ -24,6 +24,19 @@
overflow-y: auto;
}
@media only screen and (min-width:0px) and (max-width:800px){
.partnumber-box{
height: 50px;
text-align: center;
padding-top:15px;
margin-bottom:10px;
font-size: 14px;
vertical-align: middle;
word-wrap:break-word ;
cursor: pointer;
}
}
</style>
<link href="${ctx}/scripts/lobibox/css/lobibox.min.css?id=2" rel="stylesheet" type="text/css"/>
......@@ -94,10 +107,21 @@
<div class="modal-dialog" style="margin-top: 10%;width:80%;margin-left:10%;">
<div class="modal-content">
<div class="modal-header">
<div>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="modal-title" style="font-weight: 500;"><fmt:message key="button.checkout"/> </h4>
<h4 class="modal-title" id="modal-title" style="font-weight: 500;margin-right:30px;">
<fmt:message key="button.checkout"/>
<a href="" class="btn yellow right" id="findAndOut" style="top: -10px;position: relative;">
<i class="fa fa-sign-out"></i><fmt:message key="allBoxView.findAndOut"/>
</a>
</h4>
</div>
<div>
<input type="text" class="form-control" id="searchPn"/>
</div>
</div>
<div class="modal-body">
<div class="row" id="partNumberItems">
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-3">
......@@ -108,7 +132,7 @@
</div>
<div class="modal-footer">
<div id="footerBtn">
<a href="" class="btn yellow left" id="findAndOut"><i class="fa fa-sign-out"></i><fmt:message key="allBoxView.findAndOut"/></a>
<button type="button" class="btn green" onclick="lastPage()" id="lastPage">
<fmt:message key="allBoxView.lastPage"/></button>
......@@ -287,7 +311,7 @@
}
for(var index = itemPerPage * pageIndex;index<endIndex;index++){
var pn = partNumberItems[index].partNumber;
itemStr = itemStr + "<div class='col-lg-3 col-md-3 col-sm-6 col-xs-12' onclick='checkoutByPartNumber(\""+pn+"\");'> " +
itemStr = itemStr + "<div class='col-lg-3 col-md-3 col-sm-6 col-xs-6' onclick='checkoutByPartNumber(\""+pn+"\");'> " +
"<div class='"+bgColors[index%itemPerPage]+" partnumber-box'>"+pn+"</div></div>";
}
if(itemStr == ""){
......
......@@ -147,6 +147,12 @@
overflow-y: auto;
}
@media only screen and (min-width:0px) and (max-width:800px){
.lobibox-notify{
display:none;
}
}
</style>
<link href="${ctx}/scripts/lobibox/css/lobibox.min.css?id=2" rel="stylesheet" type="text/css"/>
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!