User Tools

Site Tools


rm30335

rm30335 DA Fehler 462 tauchen nicht mehr im Despatch Advice Error Report auf

rm30335 im Redmine

Nachvollziehen

  1. Smarti Admin Kundenprofile / DA Conf → AIRBUS
  2. Bestellung mit 2 Positionen mit 2 verschiedenen Final Delivery Locations
  3. Eine DA importieren, die
    1. 2 Positionen enthält, die auf diesen 2 verschiedenen Order Positionen basieren
    2. Noch schlimmer wird es wenn die 2 DA Positionen in der gleichen UX sind

Analyse

  • Ursache: In ASNManagerEJB.handleImportASN() wird geprüft, ob nach dem ersten Drittel schon schwerwiegende Fehler entdeckt wurden: this.containsCriticalErrors( container, processType ). Und wenn ja, springt man aus der Methode raus.
  • Der Code, der den Fehler verursacht, wurde für rm24209 eingebaut. Ob das für den Fix wirklich notwendig war ist aber fraglich. Zumindest auf den ersten Blick sehe ich das nicht.

Hat mit der Sache eigentlich nichts zu tun ist aber interessant:

  • Die Methode ASNXMLImportHandler.processRootElement() hat eine sehr komische Logik. Nämlich, wenn die Liste processingItemInfos Elemente enthält, dann gilt die Nachricht als erfolgreich importiert. Zumindest diese Meldung wird ausgegeben. Aber: wenn das Flag successfullyImported auf true steht, wird ein ProcessingInfo Objekt erstellt, der dann Fehler enthält.

Fix

Variante 1

Die umgekehrte Operation zu:

ClientResultMessageEntry clientMessage = 
    ErrorMsgUtil.getClientResultMessageEntry( ctx, 
                                              uiErrMsgObj, 
                                              uiErrMsgObj.getRelation() == null ? relation : uiErrMsgObj.getRelation(), 
                                              asnModel.getDespatchId(), 
                                              asnModel.getASNId(), 
                                              asnModel.getCreationDate(), 
                                              counter++ );

Also:

    /**
     * This method makes the "reverse" operation to
     * {@link #getClientResultMessageEntry(SASUserContext, UIErrorMsg, RelationModel, String, int, long, int)}
     * Unfortunately the "full reverse" is not possible, so this method tries to do it as far as it is possible.
     * @param clientMessage message to convert
     * @return converted {@link UIErrorMsg} or null if the parameter clientMessage is null.
     */
    public static UIErrorMsg convertClientResultMessageEntryToUiErrorMsg(ClientResultMessageEntry clientMessage) {
 
        if(clientMessage==null || clientMessage.isSuccess()) {
            return null;
        }
 
        UIErrorMsg uiErrMsgObj = new UIErrorMsg();
        // is NOT contained in getClientResultMessageEntry()
        uiErrMsgObj.setErrorDescription(clientMessage.getText());
 
//        Nls nls = new Nls();
//        nls.init(ctx);
//
//        int csvLineId = uiErrMsgObj.getCsvLineId();
//        String lineTxt = null;
//        if (csvLineId != -1){
//            lineTxt = nls.getText("airsupply.asn.validation.info.beginlineno", "(See the csv-file row %s1 ff.)", new String[]{"" +csvLineId});
//        }
//
//        String asnIdentifier = null;
//        if (despatchId != null && !despatchId.trim().equals("") && !uiErrMsgObj.isEnhancedMessage()) {
//            asnIdentifier = nls.getText("airsupply.asn.validation.invalidasn", "(Despatch ID %s1)", new String[]{despatchId});
//        }
//
//        String errorTxt = uiErrMsgObj.getErrorDescription();
//        if (asnIdentifier != null){
//            errorTxt += " ";
//            errorTxt += asnIdentifier;
//        }
//
//        if (lineTxt != null){
//            errorTxt += " " +lineTxt;
//        }
 
 
//        clientMessage.setIsSuccess(false);
//        clientMessage.setResultNumber(counter);
        uiErrMsgObj.setErrorCode(clientMessage.getCode());
        uiErrMsgObj.setAreaName(clientMessage.getAreaName());
//        clientMessage.setReferenceId(despatchId);
        uiErrMsgObj.setAlertCreationDate(clientMessage.getCreationDate());
//        clientMessage.setObjectCreationDate(creationDate);
 
        if( clientMessage.getCustomerGroupName()!=null
                && clientMessage.getSupplierGroupName()!=null
                && clientMessage.getSupplierNumber()!=null ) {
            RelationModel relation = new RelationModel();
            relation.setCustomerGroupName(clientMessage.getCustomerGroupName());
            relation.setSupplierGroupName(clientMessage.getSupplierGroupName());
            relation.setSupplierNo(clientMessage.getSupplierNumber());
 
            uiErrMsgObj.setRelation(relation);
        }
 
        uiErrMsgObj.setObjectId(clientMessage.getObjectId());
        uiErrMsgObj.setFieldName(clientMessage.getFieldName());
//        clientMessage.setNlsDefaultMessage(errorTxt);
        uiErrMsgObj.setPageId(clientMessage.getTargetId());
        try {
            uiErrMsgObj.setSectionName(ASN_SECTION.valueOf(clientMessage.getSectionName()));
        } catch (IllegalArgumentException e) {
            // do nothing here
        }
 
        uiErrMsgObj.setPreventRefIdLink(clientMessage.isPreventRefIdLink());
        uiErrMsgObj.setPreventSectionLink(clientMessage.isPreventSectionLink());
 
        copyRefIdList(clientMessage, uiErrMsgObj);
 
        return uiErrMsgObj;
    }
 
    private static void copyRefIdList(ClientResultMessageEntry clientMessage, UIErrorMsg uiErrMsgObj) {
        List<Map<String, String>> fromList = clientMessage.getFieldRefIds();
 
        if(fromList!=null) {
 
            List<Map<String, String>> toList = new ArrayList<>();
 
            for (Map<String, String> fromMap : fromList) {
                Map<String, String> toMap = new HashMap<>();
 
                for(Entry<String, String> fieldRefIdsEntry : fromMap.entrySet()) {
 
                    String key = fieldRefIdsEntry.getKey();
                    if (ClientResultMessageEntry.REFERENCE_KEYS.INTERNAL_OBJECTID.toString().equals(key)) {
                        if (uiErrMsgObj.getInternalObjectId()==0) {
                            uiErrMsgObj.setInternalObjectId(parseStringToIntOrDefault(fieldRefIdsEntry.getValue(), 0));
                        }
                    } else if ( ClientResultMessageEntry.REFERENCE_KEYS.INTERNAL_REFERENCEID.toString().equals(key) ) {
                        if (uiErrMsgObj.getInternalReferenceId()==0) {
                            uiErrMsgObj.setInternalReferenceId(parseStringToIntOrDefault(fieldRefIdsEntry.getValue(), 0));
                        }
                    } else if ( ClientResultMessageEntry.REFERENCE_KEYS.FILTER_NAME.toString().equals(key) ) {
                        if (StringUtils.isEmpty(uiErrMsgObj.getFilterName())) {
                            uiErrMsgObj.setFilterName(fieldRefIdsEntry.getValue());
                        }
                    } else if ( ClientResultMessageEntry.REFERENCE_KEYS.ATTRIBUTE_NAME.toString().equals(key) ) {
                        if (StringUtils.isEmpty(uiErrMsgObj.getAttributeName())) {
                            uiErrMsgObj.setAttributeName(fieldRefIdsEntry.getValue());
                        }
                    } else //noinspection StatementWithEmptyBody
                        if ( ClientResultMessageEntry.REFERENCE_KEYS.DOCUMENT_ID.toString().equals(key) ) {
//                        asnId = Integer.parseInt(fieldRefIdsEntry.getValue());
                        // do nothing for now
                    } else {
                        toMap.put(fieldRefIdsEntry.getKey(), fieldRefIdsEntry.getValue());
                    }
                }
                toList.add(toMap);
            }
            uiErrMsgObj.setFieldRefIds(toList);
        }
    }
 
    @SuppressWarnings("SameParameterValue")
    private static int parseStringToIntOrDefault(String value, int defaultInt) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return defaultInt;
        }
    }

Variante 2

Diese Variante ziehen wir vor, da der Code so gut wie gar nicht geändert werden muss. Wir nutzen aus, dass die Methode ErrorMsgUtil.handleAsnErrorReport() auch dann Reports schreibt, wenn keine übergeben werden. Sie werden dann aus den Fehlern, die im Container gespeichert sind, erzeugt.

Test

  • - Test, whether the error messages are not written twice for CSV upload
rm30335.txt · Last modified: by kalaschnikow