/** * Update Tax & Header * * @return true if header updated */ private boolean updateHeaderTax() { // Recalculate Tax for this Tax if (!getParent().isProcessed()) { if (!updateOrderTax(false)) { return false; } } // task 08999: // Avoid a possible deadlock by updating the C_Order *after* the current transaction, because at // this point we might already hold a lot of locks to different objects. // The updates in updateHeader0 will try aggregate and obtain any number of additional shared // locks. // Concrete, we observed a deadlock between this code and // M_ReceiptSchedule.propagateQtysToOrderLine() final ITrxManager trxManager = Services.get(ITrxManager.class); trxManager .getTrxListenerManager(get_TrxName()) .registerListener( new TrxListenerAdapter() { @Override public void afterCommit(final ITrx trx) { trxManager.run( new TrxRunnableAdapter() { @Override public void run(final String localTrxName) throws Exception { updateHeader0(getC_Order_ID()); } }); } }); return true; } // updateHeaderTax
/** * If the bpartner's <code>DocumentCopies</code> changes, then this method updates all unprocessed * C_Printing_Queues which reference the bpartner. The update is performed in a dedicated * transaction, after the MV's current trx is committed. * * @task * http://dewiki908/mediawiki/index.php/08958_Druck_Warteschlange_Sortierung_Massendruck_%28103271838939%29 */ @ModelChange( timings = {ModelValidator.TYPE_AFTER_CHANGE}, ifColumnsChanged = I_C_BPartner.COLUMNNAME_DocumentCopies) public void setCopiesFromBPartner(final I_C_BPartner bPartner) { final int documentCopies = bPartner.getDocumentCopies() > 0 ? bPartner.getDocumentCopies() : 1; // default final ITrxManager trxManager = Services.get(ITrxManager.class); trxManager .getTrxListenerManager(InterfaceWrapperHelper.getTrxName(bPartner)) .registerListener( new TrxListenerAdapter() { @Override public void afterCommit(final ITrx trx) { trxManager.run( new TrxRunnable() { @Override public void run(final String localTrxName) throws Exception { final Properties ctx = InterfaceWrapperHelper.getCtx(bPartner); final IQueryBL queryBL = Services.get(IQueryBL.class); // 08958: for the starts, we only update queue items that reference invoices final IQuery<I_C_DocType> invoicedocTypeQuery = queryBL .createQueryBuilder( I_C_DocType.class, ctx, ITrx.TRXNAME_ThreadInherited) .addOnlyActiveRecordsFilter() .addInArrayFilter( I_C_DocType.COLUMNNAME_DocBaseType, X_C_DocType.DOCBASETYPE_APCreditMemo, X_C_DocType.DOCBASETYPE_APInvoice, X_C_DocType.DOCBASETYPE_ARCreditMemo, X_C_DocType.DOCBASETYPE_ARInvoice, X_C_DocType.DOCBASETYPE_ARProFormaInvoice) .create(); final int updatedCount = queryBL .createQueryBuilder( I_C_Printing_Queue.class, ctx, ITrx.TRXNAME_ThreadInherited) .addOnlyActiveRecordsFilter() .addEqualsFilter( I_C_Printing_Queue.COLUMN_C_BPartner_ID, bPartner.getC_BPartner_ID()) .addEqualsFilter(I_C_Printing_Queue.COLUMN_Processed, false) .addInSubQueryFilter( I_C_Printing_Queue.COLUMN_C_DocType_ID, I_C_DocType.COLUMN_C_DocType_ID, invoicedocTypeQuery) .addNotEqualsFilter( I_C_Printing_Queue.COLUMN_Copies, documentCopies) .create() .updateDirectly() .addSetColumnValue( I_C_Printing_Queue.COLUMNNAME_Copies, documentCopies) .setExecuteDirectly(true) // just to be sure .execute(); logger.debug( "C_BPartner={}: set C_Printing_Queue.Copies={} for {} C_Printing_Queue records", new Object[] {bPartner, documentCopies, updatedCount}); } }); } }); }