Introduction
Developers of configurations that automate retail and merchandising activities frequently need algorithms that check the availability of a required product quantity in a warehouse before processing the papers. This is handled efficiently with the query language by connecting a document tabular section with a balances table in order to check balances. This section covers a few issues that developers might encounter during the implementation of this feature.
Checking balances
A query to get the balances of products available in a tabular section has the following format:
SELECT
SalesOrderContent.Items,
ItemAccountingBalance.QuantityBalance
FROM
Document.SalesOrder.Content AS SalesOrderContent
LEFT JOIN AccumulationRegister.ItemAccounting.Balance AS ItemAccountingBalance
ON ItemAccountingBalance.Items = SalesOrderContent.Items
WHERE
SalesOrderContent.Ref = &Document
Be sure to pay attention to the following factors. First of all, when a product is not available in the warehouse, the ItemAccountingBalance.QuantityBalance field has the NULL value, so any comparison with it is invalid and returns a result that is treated as the FALSE value. Take this into account when creating a query. For example, to get products whose warehouse quantities might be lower than the quantities in a document, use the following query format:
SELECT
SalesOrderContent.Items,
ItemAccounting.Balance.QuantityBalance
FROM
Document.SalesOrder.Content AS SalesOrderContent
LEFT JOIN AccumulationRegister.ItemAccounting.Balance AS ItemAccountingBalance
ON ItemAccounting.Balance.Items = SalesOrderContent.Items
WHERE
SalesOrderContent.Ref = &Document AND
(ItemAccounting.Balance.QuantityBalance < SalesOrderContent.Quantity OR
ItemAccounting.Balance.QuantityBalance IS NULL)
This query checks that the warehouse quantity of a product is less than the required quantity or the product is not available at all.
The next important factor is limiting the number of balance calculations. In this example the virtual table of balances first calculates balances for all the products and then connects the products found in the tabular section to the tabular section. To ensure the calculation of balances of only those products that are on the sales order, you can pass the limitation to the balances table (see Using filters in queries with virtual tables). The corrected query is as follows:
SELECT
SalesOrderContent.Items,
ItemAccountingBalance.QuantityBalance
FROM
Document.SalesOrder.Content AS SalesOrderContent
LEFT JOIN AccumulationRegister.ItemAccounting.Balance(,
Item IN (
SELECT Items
FROM Document.SalesOrder.Content
WHERE Ref = &Document)) AS ItemAccountingBalance
ON ItemAcountingBalance.Items = SalesOrderContent.Items
WHERE
ItemAccountingBalance.Ref = &Document AND
(ItemAccountingBalance.QuantityBalance < SalesOrderContent.Quantity OR
ItemAccountingBalance.QuantityBalance IS NULL)
Another important thing is that a document might have multiple rows with the same product. To check balances correctly, the query should be modified so that the total quantity of a product in the document is compared to the balances. The modified query is as follows:
SELECT
Content.Items,
Content.Quantity,
ItemAccountingBalances.QuantityBalance
FROM
(SELECT
SalesOrderContent.Items AS Items,
SUM(SalesOrderContent.Quantity) AS Quantity
FROM
Document.SalesOrder.Content AS SalesOrderContent
WHERE SalesOrderContent.Ref = &Document
GROUP BY SalesOrderContent.Items) AS Content
LEFT JOIN AccumulationRegister.ItemAccounting.Balance(,
Items IN (
SELECT
Document.SalesOrder.Content.Items
FROM
Document.SalesOrder.Content
WHERE
Document.SalesOrder.Content.Ref = &Document)
) AS ItemAccountingBalances
ON ItemAccountingBalances.Items = Content.Items
WHERE
(ItemAccountingBalances.QuantityBalance < Content.Quantity
OR (ItemAccountingBalances.QuantityBalance) IS NULL )
As you can see from the query, we started by calculating the total number of each product in the document and only then executed all the operations that involve the comparison of balances.
The last thing to be aware of is displaying information on insufficient product quantity to a user. As we have described in detail in Display of reference fields, in order to display product information to a user, we recommend that you get product presentation using a query and display this presentation to the user. Here is a modified query that additionally gets product presentations:
SELECT
Content.Items,
Content.Items.Presentation AS Presentation,
Content.Quantity,
ItemAccountingBalances.QuantityBalance
FROM
(SELECT
SalesOrderContent.Items AS Items,
SUM(SalesOrderContent.Quantity) AS Quantity
FROM
Document.SalesOrder.Content AS SalesOrderContent
WHERE SalesOrderContent.Ref = &Document
GROUP BY SalesOrderContent.Items) AS Content
LEFT JOIN AccumulationRegister.ItemAccounting.Balance(,
Items IN (
SELECT
Document.SalesOrder.Content.Items
FROM
Document.SalesOrder.Content
WHERE
Document.SalesOrder.Content.Ref = &Document)
) AS ItemAccountingBalances
ON ItemAccountingBalances.Items = Content.Items
WHERE
(ItemAccountingBalances.QuantityBalance < Content.Quantity
OR (ItemAccountingBalances.QuantityBalance) IS NULL )
Then you need to display the Presentation field to the user.
Example:
Result = Query.Execute();
If Not Result.IsEmpty() Then
Message("Insufficient goods:");
Selection = Result.Choose();
While Selection.Next() Do
Message(Selection.Presentation + ": required: " + Row(Selection.Quantity)
+ ", available: " + Row(Selection.QuantityBalance));
EndDo;
EndIf;
Conclusion
The section describes some specifics of checking product balances. We have provided example queries for getting data required for checking balances. You can use these examples when you implement actual queries.
Next page: Specifics of DATEDIFF function of the query language
