src/org/openbravo/materialmgmt/InventoryCountProcess.java
author Carlos Aristu <carlos.aristu@openbravo.com>
Wed, 13 Jun 2018 17:18:35 +0200
changeset 34193 12232bee10ef
parent 33876 c5d8fbd7e953
child 34236 20cd44382a65
permissions -rw-r--r--
fixes issue 38749: InventoryCountProcess registers SQL functions in a non-standard way

Register in Hibernate the SQL functions required by the InventoryCountProcess class during the initialization of the DAL layer:

- get_uuid: being already registered in the KernelSQLFunctionRegister
- to_date: there is no need of explicitly registering it, it is already registered by the corresponding PostgreSQL and Oracle dialects
- to_timestamp: being registered by default with the PostgreSQL but not with the Oracle dialect. So for PostgreSQL we are overriding the registry of this function. For this reason we are registering it in the same way as done by the PostgreSQL dialect.
- now: the same as to_timestamp function
alvaro@27872
     1
/*
alvaro@27872
     2
 *************************************************************************
alvaro@27872
     3
 * The contents of this file are subject to the Openbravo  Public  License
alvaro@27872
     4
 * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
alvaro@27872
     5
 * Version 1.1  with a permitted attribution clause; you may not  use this
alvaro@27872
     6
 * file except in compliance with the License. You  may  obtain  a copy of
alvaro@27872
     7
 * the License at http://www.openbravo.com/legal/license.html
alvaro@27872
     8
 * Software distributed under the License  is  distributed  on  an "AS IS"
alvaro@27872
     9
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
alvaro@27872
    10
 * License for the specific  language  governing  rights  and  limitations
alvaro@27872
    11
 * under the License.
alvaro@27872
    12
 * The Original Code is Openbravo ERP.
alvaro@27872
    13
 * The Initial Developer of the Original Code is Openbravo SLU
carlos@33876
    14
 * All portions are Copyright (C) 2012-2018 Openbravo SLU
alvaro@27872
    15
 * All Rights Reserved.
alvaro@27872
    16
 * Contributor(s):  ______________________________________.
alvaro@27872
    17
 ************************************************************************
alvaro@27872
    18
 */
alvaro@27872
    19
gorkaion@17134
    20
package org.openbravo.materialmgmt;
gorkaion@17134
    21
gorkaion@17171
    22
import java.text.SimpleDateFormat;
gorkaion@17134
    23
import java.util.Calendar;
gorkaion@17171
    24
import java.util.Date;
ioritz@24164
    25
import java.util.Iterator;
gorkaion@17285
    26
import java.util.List;
gorkaion@17134
    27
ioritz@24164
    28
import javax.enterprise.inject.Any;
ioritz@24164
    29
import javax.enterprise.inject.Instance;
ioritz@24164
    30
import javax.inject.Inject;
ioritz@24164
    31
gorkaion@17134
    32
import org.apache.commons.lang.time.DateUtils;
gorkaion@17273
    33
import org.apache.log4j.Logger;
gorkaion@17161
    34
import org.hibernate.Query;
ioritz@18613
    35
import org.hibernate.QueryTimeoutException;
javier@21170
    36
import org.hibernate.Session;
ioritz@18613
    37
import org.hibernate.exception.GenericJDBCException;
gorkaion@17134
    38
import org.openbravo.advpaymentmngt.utility.FIN_Utility;
gorkaion@17134
    39
import org.openbravo.base.exception.OBException;
gorkaion@17134
    40
import org.openbravo.dal.core.OBContext;
gorkaion@17161
    41
import org.openbravo.dal.core.SessionHandler;
gorkaion@17134
    42
import org.openbravo.dal.security.OrganizationStructureProvider;
gorkaion@17134
    43
import org.openbravo.dal.service.OBDal;
gorkaion@17134
    44
import org.openbravo.dal.service.OBQuery;
gorkaion@17134
    45
import org.openbravo.erpCommon.utility.OBError;
gorkaion@17134
    46
import org.openbravo.erpCommon.utility.OBMessageUtils;
javier@21170
    47
import org.openbravo.erpCommon.utility.Utility;
ioritz@24164
    48
import org.openbravo.materialmgmt.hook.InventoryCountCheckHook;
ioritz@24164
    49
import org.openbravo.materialmgmt.hook.InventoryCountProcessHook;
gorkaion@17161
    50
import org.openbravo.model.ad.access.User;
gorkaion@17134
    51
import org.openbravo.model.common.enterprise.Organization;
gorkaion@17134
    52
import org.openbravo.model.common.plm.AttributeSet;
gorkaion@17134
    53
import org.openbravo.model.common.plm.AttributeSetInstance;
gorkaion@17134
    54
import org.openbravo.model.common.plm.Product;
gorkaion@17134
    55
import org.openbravo.model.financialmgmt.calendar.Period;
gorkaion@17134
    56
import org.openbravo.model.financialmgmt.calendar.PeriodControl;
gorkaion@17134
    57
import org.openbravo.model.materialmgmt.onhandquantity.StorageDetail;
gorkaion@17134
    58
import org.openbravo.model.materialmgmt.transaction.InventoryCount;
gorkaion@17134
    59
import org.openbravo.model.materialmgmt.transaction.InventoryCountLine;
gorkaion@17134
    60
import org.openbravo.model.materialmgmt.transaction.MaterialTransaction;
gorkaion@17134
    61
import org.openbravo.scheduling.Process;
gorkaion@17134
    62
import org.openbravo.scheduling.ProcessBundle;
javier@21170
    63
import org.openbravo.service.db.DalConnectionProvider;
gorkaion@17134
    64
gorkaion@17134
    65
public class InventoryCountProcess implements Process {
gorkaion@17273
    66
  private static final Logger log4j = Logger.getLogger(InventoryCountProcess.class);
gorkaion@17134
    67
ioritz@24164
    68
  @Inject
ioritz@24164
    69
  @Any
ioritz@24164
    70
  private Instance<InventoryCountCheckHook> inventoryCountChecks;
ioritz@24164
    71
ioritz@24164
    72
  @Inject
ioritz@24164
    73
  @Any
sanjota@30754
    74
  private Instance<InventoryCountProcessHook> inventoryCountProcesses;
ioritz@24164
    75
gorkaion@17134
    76
  @Override
gorkaion@17134
    77
  public void execute(ProcessBundle bundle) throws Exception {
gorkaion@17134
    78
    OBError msg = new OBError();
gorkaion@17134
    79
    msg.setType("Success");
gorkaion@17134
    80
    msg.setTitle(OBMessageUtils.messageBD("Success"));
gorkaion@17134
    81
gorkaion@17134
    82
    try {
gorkaion@17134
    83
      // retrieve standard params
gorkaion@17134
    84
      final String recordID = (String) bundle.getParams().get("M_Inventory_ID");
gorkaion@17134
    85
      final InventoryCount inventory = OBDal.getInstance().get(InventoryCount.class, recordID);
gorkaion@17134
    86
gorkaion@17134
    87
      // lock inventory
gorkaion@17161
    88
      if (inventory.isProcessNow()) {
gorkaion@17161
    89
        throw new OBException(OBMessageUtils.parseTranslation("@OtherProcessActive@"));
gorkaion@17161
    90
      }
gorkaion@17134
    91
      inventory.setProcessNow(true);
gorkaion@17134
    92
      OBDal.getInstance().save(inventory);
gorkaion@17161
    93
      if (SessionHandler.isSessionHandlerPresent()) {
gorkaion@17161
    94
        SessionHandler.getInstance().commitAndStart();
gorkaion@17161
    95
      }
gorkaion@17134
    96
gorkaion@17161
    97
      OBContext.setAdminMode(false);
gorkaion@17161
    98
      try {
gorkaion@17134
    99
        msg = processInventory(inventory);
gorkaion@17161
   100
      } finally {
gorkaion@17161
   101
        OBContext.restorePreviousMode();
gorkaion@17134
   102
      }
gorkaion@17161
   103
gorkaion@17134
   104
      inventory.setProcessNow(false);
gorkaion@17134
   105
gorkaion@17134
   106
      OBDal.getInstance().save(inventory);
gorkaion@17134
   107
      OBDal.getInstance().flush();
gorkaion@17134
   108
gorkaion@17134
   109
      bundle.setResult(msg);
gorkaion@17134
   110
ioritz@18613
   111
      // Postgres wraps the exception into a GenericJDBCException
ioritz@18613
   112
    } catch (GenericJDBCException ge) {
ioritz@18613
   113
      log4j.error("Exception processing physical inventory", ge);
ioritz@18613
   114
      msg.setType("Error");
ioritz@18613
   115
      msg.setTitle(OBMessageUtils.messageBD(bundle.getConnection(), "Error", bundle.getContext()
ioritz@18613
   116
          .getLanguage()));
stefan@26808
   117
      msg.setMessage(ge.getSQLException().getMessage());
ioritz@18613
   118
      bundle.setResult(msg);
ioritz@18613
   119
      OBDal.getInstance().rollbackAndClose();
ioritz@18613
   120
      final String recordID = (String) bundle.getParams().get("M_Inventory_ID");
ioritz@18613
   121
      final InventoryCount inventory = OBDal.getInstance().get(InventoryCount.class, recordID);
ioritz@18613
   122
      inventory.setProcessNow(false);
ioritz@18613
   123
      OBDal.getInstance().save(inventory);
ioritz@18613
   124
      // Oracle wraps the exception into a QueryTimeoutException
ioritz@18613
   125
    } catch (QueryTimeoutException qte) {
ioritz@18613
   126
      log4j.error("Exception processing physical inventory", qte);
ioritz@18613
   127
      msg.setType("Error");
ioritz@18613
   128
      msg.setTitle(OBMessageUtils.messageBD(bundle.getConnection(), "Error", bundle.getContext()
ioritz@18613
   129
          .getLanguage()));
stefan@26808
   130
      msg.setMessage(qte.getSQLException().getMessage().split("\n")[0]);
ioritz@18613
   131
      bundle.setResult(msg);
ioritz@18613
   132
      OBDal.getInstance().rollbackAndClose();
ioritz@18613
   133
      final String recordID = (String) bundle.getParams().get("M_Inventory_ID");
ioritz@18613
   134
      final InventoryCount inventory = OBDal.getInstance().get(InventoryCount.class, recordID);
ioritz@18613
   135
      inventory.setProcessNow(false);
ioritz@18613
   136
      OBDal.getInstance().save(inventory);
gorkaion@17134
   137
    } catch (final Exception e) {
gorkaion@17285
   138
      log4j.error("Exception processing physical inventory", e);
gorkaion@17134
   139
      msg.setType("Error");
gorkaion@17285
   140
      msg.setTitle(OBMessageUtils.messageBD(bundle.getConnection(), "Error", bundle.getContext()
gorkaion@17134
   141
          .getLanguage()));
gorkaion@17134
   142
      msg.setMessage(FIN_Utility.getExceptionMessage(e));
gorkaion@17134
   143
      bundle.setResult(msg);
gorkaion@17134
   144
      OBDal.getInstance().rollbackAndClose();
gorkaion@17161
   145
      final String recordID = (String) bundle.getParams().get("M_Inventory_ID");
gorkaion@17161
   146
      final InventoryCount inventory = OBDal.getInstance().get(InventoryCount.class, recordID);
gorkaion@17161
   147
      inventory.setProcessNow(false);
gorkaion@17161
   148
      OBDal.getInstance().save(inventory);
gorkaion@17134
   149
    }
gorkaion@17134
   150
gorkaion@17134
   151
  }
gorkaion@17134
   152
gorkaion@17134
   153
  public OBError processInventory(InventoryCount inventory) throws OBException {
eduardo@23868
   154
    return processInventory(inventory, true);
eduardo@23868
   155
  }
eduardo@23868
   156
eduardo@23868
   157
  public OBError processInventory(InventoryCount inventory, boolean checkReservationQty)
eduardo@23868
   158
      throws OBException {
david@27643
   159
    return processInventory(inventory, checkReservationQty, false);
miguel@24914
   160
  }
miguel@24914
   161
miguel@24914
   162
  public OBError processInventory(InventoryCount inventory, boolean checkReservationQty,
miguel@24914
   163
      boolean checkPermanentCost) throws OBException {
gorkaion@17134
   164
    OBError msg = new OBError();
gorkaion@17134
   165
    msg.setType("Success");
gorkaion@17134
   166
    msg.setTitle(OBMessageUtils.messageBD("Success"));
gorkaion@17134
   167
    runChecks(inventory);
gorkaion@17161
   168
gorkaion@17161
   169
    StringBuffer insert = new StringBuffer();
gorkaion@17161
   170
    insert.append("insert into " + MaterialTransaction.ENTITY_NAME + "(");
gorkaion@17161
   171
    insert.append(" id ");
gorkaion@17161
   172
    insert.append(", " + MaterialTransaction.PROPERTY_ACTIVE);
gorkaion@17161
   173
    insert.append(", " + MaterialTransaction.PROPERTY_CLIENT);
gorkaion@17161
   174
    insert.append(", " + MaterialTransaction.PROPERTY_ORGANIZATION);
gorkaion@17161
   175
    insert.append(", " + MaterialTransaction.PROPERTY_CREATIONDATE);
gorkaion@17161
   176
    insert.append(", " + MaterialTransaction.PROPERTY_CREATEDBY);
gorkaion@17161
   177
    insert.append(", " + MaterialTransaction.PROPERTY_UPDATED);
gorkaion@17161
   178
    insert.append(", " + MaterialTransaction.PROPERTY_UPDATEDBY);
gorkaion@17161
   179
    insert.append(", " + MaterialTransaction.PROPERTY_MOVEMENTTYPE);
gaurav@21696
   180
    insert.append(", " + MaterialTransaction.PROPERTY_CHECKRESERVEDQUANTITY);
miguel@24914
   181
    insert.append(", " + MaterialTransaction.PROPERTY_ISCOSTPERMANENT);
gorkaion@17161
   182
    insert.append(", " + MaterialTransaction.PROPERTY_MOVEMENTDATE);
gorkaion@17161
   183
    insert.append(", " + MaterialTransaction.PROPERTY_STORAGEBIN);
gorkaion@17161
   184
    insert.append(", " + MaterialTransaction.PROPERTY_PRODUCT);
gorkaion@17161
   185
    insert.append(", " + MaterialTransaction.PROPERTY_ATTRIBUTESETVALUE);
gorkaion@17161
   186
    insert.append(", " + MaterialTransaction.PROPERTY_MOVEMENTQUANTITY);
gorkaion@17161
   187
    insert.append(", " + MaterialTransaction.PROPERTY_UOM);
gorkaion@17161
   188
    insert.append(", " + MaterialTransaction.PROPERTY_ORDERQUANTITY);
gorkaion@17161
   189
    insert.append(", " + MaterialTransaction.PROPERTY_ORDERUOM);
gorkaion@17161
   190
    insert.append(", " + MaterialTransaction.PROPERTY_PHYSICALINVENTORYLINE);
gorkaion@17171
   191
    insert.append(", " + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE);
gorkaion@17161
   192
    // select from inventory line
gorkaion@17161
   193
    insert.append(" ) \n select get_uuid() ");
gorkaion@17161
   194
    insert.append(", e." + InventoryCountLine.PROPERTY_ACTIVE);
gorkaion@17161
   195
    insert.append(", e." + InventoryCountLine.PROPERTY_CLIENT);
gorkaion@17161
   196
    insert.append(", e." + InventoryCountLine.PROPERTY_ORGANIZATION);
gorkaion@17161
   197
    insert.append(", now()");
gorkaion@17161
   198
    insert.append(", u");
gorkaion@17161
   199
    insert.append(", now()");
gorkaion@17161
   200
    insert.append(", u");
gorkaion@17161
   201
    insert.append(", 'I+'");
eduardo@23868
   202
    // We have to set check reservation quantity flag equal to checkReservationQty
miguel@24914
   203
    // InventoryCountLine.PROPERTY_ACTIVE-->> Y
miguel@24914
   204
    // InventoryCountLine.PROPERTY_PHYSINVENTORY + "." + InventoryCount.PROPERTY_PROCESSED -->> N
eduardo@23868
   205
    if (checkReservationQty) {
eduardo@23868
   206
      insert.append(", e." + InventoryCountLine.PROPERTY_ACTIVE);
eduardo@23868
   207
    } else {
eduardo@23868
   208
      insert.append(", e." + InventoryCountLine.PROPERTY_PHYSINVENTORY + "."
eduardo@23868
   209
          + InventoryCount.PROPERTY_PROCESSED);
eduardo@23868
   210
    }
miguel@24914
   211
    // We have to set check permanent cost flag
miguel@24914
   212
    // InventoryCountLine.PROPERTY_ACTIVE-->> Y
miguel@24914
   213
    // InventoryCountLine.PROPERTY_PHYSINVENTORY + "." + InventoryCount.PROPERTY_PROCESSED -->> N
miguel@24914
   214
    if (checkPermanentCost) {
miguel@24914
   215
      insert.append(", e." + InventoryCountLine.PROPERTY_ACTIVE);
miguel@24914
   216
    } else {
miguel@24914
   217
      insert.append(", e." + InventoryCountLine.PROPERTY_PHYSINVENTORY + "."
miguel@24914
   218
          + InventoryCount.PROPERTY_PROCESSED);
miguel@24914
   219
    }
gorkaion@17161
   220
    insert.append(", e." + InventoryCountLine.PROPERTY_PHYSINVENTORY + "."
gorkaion@17161
   221
        + InventoryCount.PROPERTY_MOVEMENTDATE);
gorkaion@17161
   222
    insert.append(", e." + InventoryCountLine.PROPERTY_STORAGEBIN);
gorkaion@17161
   223
    insert.append(", e." + InventoryCountLine.PROPERTY_PRODUCT);
gorkaion@17161
   224
    insert.append(", asi");
gorkaion@17161
   225
    insert.append(", e." + InventoryCountLine.PROPERTY_QUANTITYCOUNT + " - COALESCE(" + "e."
gorkaion@17161
   226
        + InventoryCountLine.PROPERTY_BOOKQUANTITY + ", 0)");
gorkaion@17161
   227
    insert.append(", e." + InventoryCountLine.PROPERTY_UOM);
gorkaion@17161
   228
    insert.append(", e." + InventoryCountLine.PROPERTY_ORDERQUANTITY + " - COALESCE(" + "e."
gorkaion@17161
   229
        + InventoryCountLine.PROPERTY_QUANTITYORDERBOOK + ", 0)");
gorkaion@17161
   230
    insert.append(", e." + InventoryCountLine.PROPERTY_ORDERUOM);
gorkaion@17161
   231
    insert.append(", e");
gorkaion@17171
   232
    insert.append(", to_timestamp(to_char(:currentDate), to_char('DD-MM-YYYY HH24:MI:SS'))");
gorkaion@17161
   233
    insert.append(" \nfrom " + InventoryCountLine.ENTITY_NAME + " as e");
gorkaion@17161
   234
    insert.append(" , " + User.ENTITY_NAME + " as u");
gorkaion@17161
   235
    insert.append(" , " + AttributeSetInstance.ENTITY_NAME + " as asi");
carlos@21090
   236
    insert.append(" , " + Product.ENTITY_NAME + " as p");
gorkaion@17161
   237
    insert.append(" \nwhere e." + InventoryCountLine.PROPERTY_PHYSINVENTORY + ".id = :inv");
carlos@23452
   238
    insert.append(" and (e." + InventoryCountLine.PROPERTY_QUANTITYCOUNT + " != e."
carlos@21092
   239
        + InventoryCountLine.PROPERTY_BOOKQUANTITY);
carlos@23452
   240
    insert.append(" or e." + InventoryCountLine.PROPERTY_ORDERQUANTITY + " != e."
carlos@23452
   241
        + InventoryCountLine.PROPERTY_QUANTITYORDERBOOK + ")");
gorkaion@17161
   242
    insert.append(" and u.id = :user");
gorkaion@17161
   243
    insert.append(" and asi.id = COALESCE(e." + InventoryCountLine.PROPERTY_ATTRIBUTESETVALUE
gorkaion@17166
   244
        + ".id , '0')");
carlos@21090
   245
    // Non Stockable Products should not generate warehouse transactions
carlos@21091
   246
    insert.append(" and e." + InventoryCountLine.PROPERTY_PRODUCT + ".id = p.id and p."
carlos@21091
   247
        + Product.PROPERTY_STOCKED + " = 'Y' and p." + Product.PROPERTY_PRODUCTTYPE + " = 'I'");
gorkaion@17161
   248
gorkaion@17161
   249
    Query queryInsert = OBDal.getInstance().getSession().createQuery(insert.toString());
gorkaion@17161
   250
    queryInsert.setString("inv", inventory.getId());
asier@29775
   251
    queryInsert.setString("user", OBContext.getOBContext().getUser().getId());
gorkaion@17171
   252
    final SimpleDateFormat dateFormatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
gorkaion@17171
   253
    queryInsert.setString("currentDate", dateFormatter.format(new Date()));
eduardo@23868
   254
    // queryInsert.setBoolean("checkReservation", checkReservationQty);
gorkaion@17161
   255
    queryInsert.executeUpdate();
gorkaion@17161
   256
david@32178
   257
    if (!"C".equals(inventory.getInventoryType()) && !"O".equals(inventory.getInventoryType())) {
gorkaion@17161
   258
      checkStock(inventory);
gorkaion@17134
   259
    }
gorkaion@17161
   260
ioritz@24164
   261
    try {
ioritz@24164
   262
      executeHooks(inventoryCountProcesses, inventory);
ioritz@24164
   263
    } catch (Exception e) {
ioritz@24164
   264
      OBException obException = new OBException(e.getMessage(), e.getCause());
ioritz@24164
   265
      throw obException;
ioritz@24164
   266
    }
ioritz@24164
   267
gorkaion@17161
   268
    inventory.setProcessed(true);
gorkaion@17134
   269
    return msg;
gorkaion@17134
   270
  }
gorkaion@17134
   271
gorkaion@17134
   272
  private void runChecks(InventoryCount inventory) throws OBException {
ioritz@24164
   273
ioritz@24164
   274
    try {
ioritz@24164
   275
      executeHooks(inventoryCountChecks, inventory);
ioritz@24164
   276
    } catch (Exception e) {
ioritz@24164
   277
      OBException obException = new OBException(e.getMessage(), e.getCause());
ioritz@24164
   278
      throw obException;
ioritz@24164
   279
    }
ioritz@24164
   280
gorkaion@17134
   281
    if (inventory.isProcessed()) {
gorkaion@17134
   282
      throw new OBException(OBMessageUtils.parseTranslation("@AlreadyPosted@"));
gorkaion@17134
   283
    }
gorkaion@17134
   284
    // Products without attribute set.
gorkaion@17134
   285
    StringBuffer where = new StringBuffer();
gorkaion@17134
   286
    where.append(" as icl");
gorkaion@17134
   287
    where.append("   join icl." + InventoryCountLine.PROPERTY_PRODUCT + " as p");
gorkaion@17161
   288
    where.append("   join p." + Product.PROPERTY_ATTRIBUTESET + " as aset");
gorkaion@17161
   289
    where.append(" where icl." + InventoryCountLine.PROPERTY_PHYSINVENTORY + ".id = :inventory");
gorkaion@17161
   290
    where.append("   and aset." + AttributeSet.PROPERTY_REQUIREATLEASTONEVALUE + " = true");
victor@21430
   291
    where.append("   and coalesce(p." + Product.PROPERTY_USEATTRIBUTESETVALUEAS + ", '-') <> 'F'");
gorkaion@17134
   292
    where.append("   and coalesce(icl." + InventoryCountLine.PROPERTY_ATTRIBUTESETVALUE
gorkaion@17134
   293
        + ", '0') = '0'");
gorkaion@17134
   294
    where.append("  order by icl." + InventoryCountLine.PROPERTY_LINENO);
gorkaion@17134
   295
    OBQuery<InventoryCountLine> iclQry = OBDal.getInstance().createQuery(InventoryCountLine.class,
gorkaion@17134
   296
        where.toString());
gorkaion@17161
   297
    iclQry.setNamedParameter("inventory", inventory.getId());
gorkaion@17285
   298
    iclQry.setMaxResult(1);
gorkaion@17285
   299
    Object icl = iclQry.uniqueResult();
gorkaion@17285
   300
    if (icl != null) {
gorkaion@17134
   301
      throw new OBException(OBMessageUtils.parseTranslation("@Inline@ "
gorkaion@17285
   302
          + ((InventoryCountLine) icl).getLineNo() + " @productWithoutAttributeSet@"));
gorkaion@17134
   303
    }
gorkaion@17134
   304
gorkaion@17134
   305
    // duplicated product
gorkaion@17134
   306
    where = new StringBuffer();
gorkaion@17134
   307
    where.append(" as icl");
gorkaion@17161
   308
    where.append(" where icl." + InventoryCountLine.PROPERTY_PHYSINVENTORY + ".id = :inventory");
gorkaion@17134
   309
    where.append("   and exists (select 1 from " + InventoryCountLine.ENTITY_NAME + " as icl2");
gorkaion@17134
   310
    where.append("       where icl." + InventoryCountLine.PROPERTY_PHYSINVENTORY + " = icl2."
gorkaion@17134
   311
        + InventoryCountLine.PROPERTY_PHYSINVENTORY);
gorkaion@17161
   312
    where.append("         and icl." + InventoryCountLine.PROPERTY_PRODUCT + " = icl2."
gorkaion@17134
   313
        + InventoryCountLine.PROPERTY_PRODUCT);
gorkaion@17161
   314
    where.append("         and coalesce(icl." + InventoryCountLine.PROPERTY_ATTRIBUTESETVALUE
gorkaion@17134
   315
        + ", '0') = coalesce(icl2." + InventoryCountLine.PROPERTY_ATTRIBUTESETVALUE + ", '0')");
pandeeswari@20686
   316
    where.append("         and coalesce(icl." + InventoryCountLine.PROPERTY_ORDERUOM
pandeeswari@20686
   317
        + ", '0') = coalesce(icl2." + InventoryCountLine.PROPERTY_ORDERUOM + ", '0')");
carlos@23452
   318
    where.append(" and coalesce(icl." + InventoryCountLine.PROPERTY_UOM + ", '0') = coalesce(icl2."
carlos@23452
   319
        + InventoryCountLine.PROPERTY_UOM + ", '0')");
gorkaion@17161
   320
    where.append("         and icl." + InventoryCountLine.PROPERTY_STORAGEBIN + " = icl2."
gorkaion@17134
   321
        + InventoryCountLine.PROPERTY_STORAGEBIN);
gorkaion@17161
   322
    where.append("         and icl." + InventoryCountLine.PROPERTY_LINENO + " <> icl2."
gorkaion@17161
   323
        + InventoryCountLine.PROPERTY_LINENO + ")");
gorkaion@17134
   324
    where.append(" order by icl." + InventoryCountLine.PROPERTY_PRODUCT);
gorkaion@17134
   325
    where.append(", icl." + InventoryCountLine.PROPERTY_ATTRIBUTESETVALUE);
gorkaion@17134
   326
    where.append(", icl." + InventoryCountLine.PROPERTY_STORAGEBIN);
gorkaion@17134
   327
    where.append(", icl." + InventoryCountLine.PROPERTY_ORDERUOM);
gorkaion@17134
   328
    where.append(", icl." + InventoryCountLine.PROPERTY_LINENO);
gorkaion@17134
   329
    iclQry = OBDal.getInstance().createQuery(InventoryCountLine.class, where.toString());
gorkaion@17161
   330
    iclQry.setNamedParameter("inventory", inventory.getId());
gorkaion@17285
   331
    List<InventoryCountLine> iclList = iclQry.list();
gorkaion@17285
   332
    if (!iclList.isEmpty()) {
gorkaion@17134
   333
      String lines = "";
gorkaion@17285
   334
      for (InventoryCountLine icl2 : iclList) {
gorkaion@17285
   335
        lines += icl2.getLineNo().toString() + ", ";
gorkaion@17134
   336
      }
gorkaion@17134
   337
      throw new OBException(OBMessageUtils.parseTranslation("@Thelines@ " + lines
gorkaion@17134
   338
          + "@sameInventorylines@"));
gorkaion@17134
   339
    }
gorkaion@17134
   340
gorkaion@17134
   341
    Organization org = inventory.getOrganization();
gorkaion@17134
   342
    if (!org.isReady()) {
gorkaion@17134
   343
      throw new OBException(OBMessageUtils.parseTranslation("@OrgHeaderNotReady@"));
gorkaion@17134
   344
    }
gorkaion@17134
   345
    if (!org.getOrganizationType().isTransactionsAllowed()) {
gorkaion@17134
   346
      throw new OBException(OBMessageUtils.parseTranslation("@OrgHeaderNotTransAllowed@"));
gorkaion@17134
   347
    }
gorkaion@17134
   348
    OrganizationStructureProvider osp = OBContext.getOBContext().getOrganizationStructureProvider(
gorkaion@17134
   349
        inventory.getClient().getId());
gorkaion@17134
   350
    Organization headerLEorBU = osp.getLegalEntityOrBusinessUnit(org);
gorkaion@17134
   351
    iclQry = OBDal.getInstance().createQuery(
gorkaion@17134
   352
        InventoryCountLine.class,
gorkaion@17161
   353
        InventoryCountLine.PROPERTY_PHYSINVENTORY + ".id = :inventory and "
gorkaion@17161
   354
            + InventoryCountLine.PROPERTY_ORGANIZATION + ".id <> :organization");
gorkaion@17161
   355
    iclQry.setNamedParameter("inventory", inventory.getId());
gorkaion@17161
   356
    iclQry.setNamedParameter("organization", org.getId());
gorkaion@17285
   357
    iclList = iclQry.list();
gorkaion@17285
   358
    if (!iclList.isEmpty()) {
gorkaion@17285
   359
      for (InventoryCountLine icl2 : iclList) {
gorkaion@17134
   360
        if (!headerLEorBU.getId().equals(
asier@29776
   361
            osp.getLegalEntityOrBusinessUnit(icl2.getOrganization()).getId())) {
gorkaion@17134
   362
          throw new OBException(OBMessageUtils.parseTranslation("@LinesAndHeaderDifferentLEorBU@"));
gorkaion@17134
   363
        }
gorkaion@17134
   364
      }
gorkaion@17134
   365
    }
gorkaion@17134
   366
    if (headerLEorBU.getOrganizationType().isLegalEntityWithAccounting()) {
gorkaion@17134
   367
      where = new StringBuffer();
gorkaion@17173
   368
      where.append(" as pc ");
gorkaion@17173
   369
      where.append("   join pc." + PeriodControl.PROPERTY_PERIOD + " as p");
gorkaion@17161
   370
      where.append(" where p." + Period.PROPERTY_STARTINGDATE + " <= :dateStarting");
gorkaion@17173
   371
      where.append("   and p." + Period.PROPERTY_ENDINGDATE + " >= :dateEnding");
gorkaion@17173
   372
      where.append("   and pc." + PeriodControl.PROPERTY_DOCUMENTCATEGORY + " = 'MMI' ");
gorkaion@17173
   373
      where.append("   and pc." + PeriodControl.PROPERTY_ORGANIZATION + ".id = :org");
gorkaion@17173
   374
      where.append("   and pc." + PeriodControl.PROPERTY_PERIODSTATUS + " = 'O'");
gorkaion@17173
   375
      OBQuery<PeriodControl> pQry = OBDal.getInstance().createQuery(PeriodControl.class,
gorkaion@17173
   376
          where.toString());
gorkaion@17173
   377
      pQry.setFilterOnReadableClients(false);
gorkaion@17173
   378
      pQry.setFilterOnReadableOrganization(false);
gorkaion@17134
   379
      pQry.setNamedParameter("dateStarting", inventory.getMovementDate());
gorkaion@17134
   380
      pQry.setNamedParameter("dateEnding",
gorkaion@17134
   381
          DateUtils.truncate(inventory.getMovementDate(), Calendar.DATE));
gorkaion@17161
   382
      pQry.setNamedParameter("org", osp.getPeriodControlAllowedOrganization(org).getId());
gorkaion@17285
   383
      pQry.setMaxResult(1);
gorkaion@17285
   384
      if (pQry.uniqueResult() == null) {
gorkaion@17134
   385
        throw new OBException(OBMessageUtils.parseTranslation("@PeriodNotAvailable@"));
gorkaion@17134
   386
      }
gorkaion@17134
   387
    }
gorkaion@17134
   388
  }
gorkaion@17134
   389
gorkaion@17161
   390
  private void checkStock(InventoryCount inventory) {
javier@21170
   391
    String attribute;
javier@21170
   392
    final StringBuilder hqlString = new StringBuilder();
javier@21170
   393
    hqlString.append("select sd.id ");
javier@21170
   394
    hqlString.append(" from MaterialMgmtInventoryCountLine as icl");
staff@32978
   395
    hqlString.append(" , MaterialMgmtStorageDetail as sd");
staff@32978
   396
    hqlString.append(" , Locator as l");
staff@32978
   397
    hqlString.append(" , MaterialMgmtInventoryStatus as invs");
carlos@33876
   398
    hqlString.append(" where icl.physInventory.id = :physInventoryId");
staff@32978
   399
    hqlString.append("   and sd.product = icl.product");
staff@32978
   400
    hqlString.append("   and (sd.quantityOnHand < 0");
staff@32978
   401
    hqlString.append("     or sd.onHandOrderQuanity < 0");
javier@21170
   402
    hqlString.append("     )");
staff@32978
   403
    // Check only negative Stock for the Bins of the Lines of the Physical Inventory
staff@32978
   404
    hqlString.append("   and sd.storageBin.id = icl.storageBin.id");
staff@32978
   405
    hqlString.append("   and l.id = icl.storageBin.id");
staff@32978
   406
    hqlString.append("   and l.inventoryStatus.id = invs.id");
staff@32978
   407
    hqlString.append("   and invs.overissue = false");
staff@32978
   408
    hqlString.append(" order by icl.lineNo");
javier@21170
   409
javier@21170
   410
    final Session session = OBDal.getInstance().getSession();
javier@21170
   411
    final Query query = session.createQuery(hqlString.toString());
carlos@33876
   412
    query.setParameter("physInventoryId", inventory.getId());
javier@21170
   413
    query.setMaxResults(1);
javier@21170
   414
javier@21170
   415
    if (!query.list().isEmpty()) {
javier@21170
   416
      StorageDetail storageDetail = OBDal.getInstance().get(StorageDetail.class,
javier@21170
   417
          query.list().get(0).toString());
javier@21170
   418
      attribute = (!storageDetail.getAttributeSetValue().getIdentifier().isEmpty()) ? " @PCS_ATTRIBUTE@ '"
javier@21170
   419
          + storageDetail.getAttributeSetValue().getIdentifier() + "', "
javier@21170
   420
          : "";
jorge@26515
   421
      throw new OBException(Utility
javier@21170
   422
          .messageBD(new DalConnectionProvider(), "insuffient_stock",
javier@21170
   423
              OBContext.getOBContext().getLanguage().getLanguage())
javier@21170
   424
          .replaceAll("%1", storageDetail.getProduct().getIdentifier()).replaceAll("%2", attribute)
javier@21170
   425
          .replaceAll("%3", storageDetail.getUOM().getIdentifier())
jorge@26515
   426
          .replaceAll("%4", storageDetail.getStorageBin().getIdentifier()));
gorkaion@17134
   427
    }
gorkaion@17134
   428
  }
ioritz@24164
   429
ioritz@24164
   430
  private void executeHooks(Instance<? extends Object> hooks, InventoryCount inventory)
ioritz@24164
   431
      throws Exception {
ioritz@24164
   432
    if (hooks != null) {
ioritz@24164
   433
      for (Iterator<? extends Object> procIter = hooks.iterator(); procIter.hasNext();) {
ioritz@24164
   434
        Object proc = procIter.next();
ioritz@24164
   435
        if (proc instanceof InventoryCountProcessHook) {
ioritz@24164
   436
          ((InventoryCountProcessHook) proc).exec(inventory);
ioritz@24164
   437
        } else {
ioritz@24164
   438
          ((InventoryCountCheckHook) proc).exec(inventory);
ioritz@24164
   439
        }
ioritz@24164
   440
      }
ioritz@24164
   441
    }
ioritz@24164
   442
  }
gorkaion@17134
   443
}