|
08.08.2019, 14:57 | #1 |
Участник
|
AX2012 R3 Тормозит формирование РН
Добрый день! AX2012 R3
Формирование расходных накладных происходит медленно, при трассировке и выявлении проблемы, выяснился неприятный момент, а именнно: В методе setEstimate: X++: /** Returns true if the estimated amount is calculated and has changed **/ server boolean setEstimate(SalesTotals _salesTotals = null) { SalesTotals salesTotals; SalesUpdate qtySpec; CustParameters custParameters = CustParameters::find(); TypeOfCreditmaxCheck typeOfCreditmaxCheck = custParameters.CreditMaxCheck; boolean hasEstimatedChanged; AmountMST estimatedOld; MCRSalesOrderTotals mcrSalesOrderTotals; hasEstimatedChanged = false; //Total estimate for the order would be calculated on order save, if credit limit check is enabled for the company. if (this.custTable_CustAccount().shouldEstimateBeCalculated()) { qtySpec = (typeOfCreditmaxCheck == TypeOfCreditmaxCheck::BalanceDelivered ? SalesUpdate::PackingSlip : typeOfCreditmaxCheck == TypeOfCreditmaxCheck::BalanceAll ? SalesUpdate::All : 0); if (qtySpec && this.isCreditCheckEligible()) { estimatedOld = this.Estimate; if (this.mcrIsCallCenter()) { if (qtySpec == SalesUpdate::All) { mcrSalesOrderTotals = new MCRSalesOrderTotals(this); this.Estimate = Currency::amountCur2MST(mcrSalesOrderTotals.getRemainingOrder(), this.CurrencyCode); } else { salesTotals = SalesTotals::construct(this, qtySpec); this.Estimate = Currency::amountCur2MST(salesTotals.totalAmount(), this.CurrencyCode); } } else { salesTotals = (_salesTotals == null) ? SalesTotals::construct(this, qtySpec) : _salesTotals; this.Estimate = Currency::amountCur2MST(salesTotals.totalAmount(), this.CurrencyCode, this.fixedExchRate()); } hasEstimatedChanged = (this.Estimate != estimatedOld); } } this.Touched = NoYes::No; return hasEstimatedChanged; } MCRSalesOrderTotals Внутри класса MCRSalesOrderTotals вызывается метод calcInvoicedExistMultiple с жутким запросом приводящем к тормозам в базе (время выполнения 10-15 секунд, используется tempdb для операции HashMatch в плане): X++: select sum(EndDisc), sum(InvoiceAmount), sum(SalesBalance), sum(SumMarkup), sum(SumTax) from custInvoiceJour where custInvoiceJour.RefNum == RefNum::SalesOrder notexists join custInvoiceSalesLink where custInvoiceJour.SalesId == custInvoiceSalesLink.SalesId && custInvoiceJour.InvoiceDate == custInvoiceSalesLink.InvoiceDate && custInvoiceJour.InvoiceId == custInvoiceSalesLink.InvoiceId && custInvoiceSalesLink.OrigSalesId != _salesTable.SalesId; Обойти сей неприятный момент возможно, отключив "центр обработки вызовов"(метод mcrIsCallCenter()) но всё-таки может есть решения без выпиливания функционала? |
|
08.08.2019, 15:29 | #2 |
Участник
|
Что то в запросе явно не хватает условия либо custInvoiceJour.SalesId = _salesTable.SalesId, либо custInvoiceSalesLink.SalesId = _salesTable.salesId.
Метод как я понимаю считает итоги по накладным с несколькими заказами, куда входит наш заказ, а не вообще по всем накладным с несколькими заказами, зачем все то считать ? См. метод calcInvoiced откуда он вызывается. А в целом, если вы функционал не используете, отключите конф ключ и будет счастье, MS вроде как рекомендует включать только то, что используете)
__________________
Sergey Nefedov |
|
08.08.2019, 17:25 | #3 |
Administrator
|
Цитата:
Тормоза придает условие custInvoiceSalesLink.OrigSalesId != _salesTable.SalesId; Нужно неравенство пытаться превращать в равенство
__________________
Возможно сделать все. Вопрос времени |
|
08.08.2019, 18:00 | #4 |
Участник
|
Я, может быть, как-то не понял логику работы, но получается, что тут мы суммируем вообще все накладные, разноска которых была запущена не из текущего заказа, ну и далее, тоже делаем с накладными расходами.
Ведь единственное ограничение на выборку это: X++: custInvoiceSalesLink.OrigSalesId != _salesTable.SalesId |
|
08.08.2019, 18:32 | #5 |
Участник
|
А чего это условие то не корректное ? Жаль что полностью код, не вставили из метода с комментарием, а выглядит он вот так :
X++: // There is at least one summary invoice so need to process each invoice separately. // [B]Select all non-summmary invoices[/B]. If no other record exists in CustInvoiceSalesLink // with a different origSalesId then there is only one sales order on the invoice and // therefore it is a non-summary invoice. select sum(EndDisc), sum(InvoiceAmount), sum(SalesBalance), sum(SumMarkup), sum(SumTax) from custInvoiceJour where custInvoiceJour.RefNum == RefNum::SalesOrder notexists join custInvoiceSalesLink where custInvoiceJour.SalesId == custInvoiceSalesLink.SalesId && custInvoiceJour.InvoiceDate == custInvoiceSalesLink.InvoiceDate && custInvoiceJour.InvoiceId == custInvoiceSalesLink.InvoiceId && custInvoiceSalesLink.OrigSalesId != _salesTable.SalesId; Поэтому как мне кажется надо в три запроса добавить условие custInvoiceJour.SalesId = _salesTable.SalesId, которые содержат notexists join в этом методе. Насчет равенства это да, но навскидку пока, быстро не придумал, как выбрать такие накладные без not exists join, Сам метод считает сумму которая в накладных из данного заказа и считает ее так = сумма всех накладных только по этому заказу + доля из накладных где наш заказ включен как один из нескольких. А вообще если не используете ключ отключите его, проблемы уйдут не только в этом методе.
__________________
Sergey Nefedov |
|
|
За это сообщение автора поблагодарили: sukhanchik (4). |
09.08.2019, 07:43 | #6 |
Administrator
|
А... прошу прощения... Ступил. Да, тогда все логично.
__________________
Возможно сделать все. Вопрос времени |
|
30.08.2019, 16:25 | #7 |
Участник
|
Добавили условие custInvoiceJour.SalesId = _salesTable.SalesId, всё залетало! Спасибо за совет и поддержку!
|
|
02.09.2019, 12:13 | #8 |
Участник
|
|
|
Теги |
mcrsalesordertotals |
|
|