Changing average price in Material Master (MM02) programmatically - abap

I want to programmatically change the moving/average price(s) of materials for the following special case:
VPRSV = 'S' (Standard price)
MLMAA = 'X' (Material Ledger activated)
MLAST = '3' (Material Price Determination = '3' (Single-/Multilevel))
period = current
It has to work when there is already a material document for the given material in the current period. All other special cases that I need are solved.
I am searching for the function module equivalent of changing the moving average price using MM02, not MR21.
Maybe BAPI_MATVAL_PRICE_CHANGE is what I'm searching for?
What confuses me is that I cannot find a parameter that determines that I want to change the moving average price and not the standard price. Did I miss a parameter? If not, does it change the standard price or moving average price?
And I'm not sure whether this function module is the equivalent of MM02 or MR21.

no, there is not such a function module. But you can use Bapi BAPI_MATVAL_PRICE_CHANGE to post price differences to ML. With this you can adjust your price to the value that you want.

You should use BAPI_MATERIAL_SAVEDATA to do this. Several mandatory structures should be filled for the successful update of average price:
HEADDATA-MATERIAL = P_MATNR. "material number
HEADDATA-ACCOUNT_VIEW = 'X'.
VALDATA-VAL_AREA = P_BWKEY. "valuation area
VALDATA-VAL_TYPE = P_BWTAR. "valuation type
VALDATA-MOVING_PR = P_STPRS. "new value of moving price
VALDATAX-VAL_AREA = P_BWKEY. "valuation area for tax accounting
VALDATAX-VAL_TYPE = P_BWTAR. "valuation type for tax accounting
VALDATAX-MOVING_PR = 'X'. "update indicator
CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA'
EXPORTING
HEADDATA = HEADDATA
VALUATIONDATA = VALDATA
VALUATIONDATAX = VALDATAX
IMPORTING
RETURN = BAPI_RETURN
TABLES
MATERIALDESCRIPTION = INT_MAKT
.

Related

Odoo 14 - I cannot see the amount in words in a report

When I want to add the amount in words in a report it does not show anything. Please help.
Levi
You have the field for amount in word?You can change your language.
amount_words = fields.Char(
'Amount in Words:',
help="The invoice total amount in words is automatically
generated by the system..few languages are supported
currently",
compute='_compute_num2words')
def _compute_num2words(self):
self.amount_words = (num2words(
self.amount_total, lang='en')).upper()

Google Data Studio incorrect calculated metrics

I am creating calculated metrics in Data Studio and I am having trouble with the results.
Metric 1 uses this formula:
COUNT_DISTINCT(CASE WHEN ( Event Category = "ABC" AND Event Action = "XXX" AND Event Label = "123" ) THEN ga clientId (user) ELSE " " END )
[[To count the events with distinct clientIds]]
Metric 2 uses this formula:
COUNT_DISTINCT(CASE WHEN ( Event Category = "ABC" AND Event Action = "YYY" AND Event Label = "456" ) THEN ga clientId (user) ELSE " " END )
[[To count the events with distinct clientIds]]
Metric 3 uses this formula:
COUNT_DISTINCT(CASE WHEN ( Event Category = "ABC" AND Event Action = "ZZZ" AND Event Label = "789" ) THEN userId(user) ELSE " " END )
[[To count the events with distinct userIds]]
The formulas work fine and when I do Metric 2/ Metric 1 the number is correct for a one day time span. When I do Metric 3/Metric 2 the number is wrong. Why is this? It doesn't make sense to me since they are both numerical values.
Also, when I increase the date range the Metric 2 / Metric 1 is incorrect too! Any ideas why these are not working?
If you are aggregating over a certain amount of data, then these calculations will not be exact; they will be approximations.
I have noticed that Google Data Studio is more accurate with data properly loaded into BigQuery rather than data loaded through something else like a PostgreSQL connector. Otherwise, APPROX_COUNT_DISTINCT may be used.

SQL error with nested SELECT

The error is 'Operation must use an updatable query'.
I am trying to update the 'orders' table with the information below, however only the price of 1 item will be provided through a text box and I am trying to calculate the total order value using the quantity ordered, which will already be in this table.
The code below includes the data taken from the variables. With the 2 in 'VAT = 2' and 'price = 2' being the price of one single unit (£2.00). The total order value will be stored within the 'price' field and the VAT should be calculated using the same code, but times by 0.2 to give the 20% VAT.
UPDATE orders
SET Invoice_number = 'IN9999',
delivery_note_number = 'DN6000',
price =2 *
(SELECT quantity
FROM orders
WHERE purchase_order_number = 'PO7512'
),
VAT = (2 *
(SELECT quantity
FROM orders
WHERE purchase_order_number = 'PO7512'
)/100) * 20,
shipping = 3
WHERE purchase_order_number = 'PO7512'
Maybe I can't use nested query's this way. I'm not sure, but any help would be appreciated :) Thanks!
Instead of subquerying, you can access the whole record directly in the update, like so:
UPDATE Orders
SET Invoice_number = 'IN9999',
Delivery_note_number = 'DN6000',
Price = 2 * quantity,
VAT = (40 * quantity)/100,
Shipping = 3
WHERE purchase_order_number = 'PO7512'
Note that with fractions it's always better to multiply first and divide later.

Find materials by bill of material

I have a stlnr and a stlal and I want to find all materials in a bill of material using these two fields. I have no idea how to do that, so please help :)
the tables you need to look at are STKO (header), STAS (position selection) and STPO (positions). You need to know the type of BOM, which is in field STKO~STLTY. Using the type and your STLNR you can get the header row from table STKO. The STKO entry is connected to STAS using STLTY, STLNR and STLAL. Table STPO contains the actual BOM positions and is connected to STAS using STLTY, STLNR and STLKN (which is in STAS but not in STKO, which is why you need table STAS too).
You also may need to look at table STPU which is connected to STPO and contains subelements within a BOM position. In our system STPU is completly empty but that may not be the case in yours.
You can call the FM CABM_READ_BOM_ITEM, you will need the following:
CALL FUNCTION 'CABM_READ_BOM_ITEM'
EXPORTING
i_stlty = i_stlty
i_stlnr = i_stlnr
i_stlal = i_stlal
i_date_from = i_date_from
* I_DATE_TO = I_DATE_TO
* I_WERKS = I_WERKS
TABLES
exp_bom_item = exp_bom_item
* EXCEPTIONS
* NO_RECORD_FOUND = 1
Which means you will need STLTY, as it is part of the key of STKO.

Updating a field within a table based on a field within the same table

HI ALL
I wish to update a row within my table from a row within that same table,
I have a table called INVENTORY. it stores PRICES for products.
I have SALES codes and I have STOCK codes which are related.
I wish to transfer all the PRICING from the SALES codes to the STOCK codes.
I wish to do something like this:
update INVENTORY
set PRICE = (SELECT PRICE WHERE CODE = "SALES CODE EQUIVALENT OF THE STOCK CODE IM IN")
WHERE
CODE = "SOME STOCK CODE"
a SALES CODE would look like this "U_12345", its STOCK code equivalent would look like "S_12345"
thanks
You're very close, you just need to specify which table you're selecting from as part of your sub-query...
update INVENTORY
set PRICE = (SELECT PRICE FROM your_table WHERE CODE = "SALES CODE EQUIVALENT OF THE STOCK CODE IM IN")
WHERE
CODE = "SOME STOCK CODE"
Even if "your_table" is INVENTORY, you still need to specify it in there.
The only time it gets 'tricky' is when your selecting from the same table that you're update, AND when you need a value from the updated record in the SELECT statement. In that case you need to differentiate between the two references, using an alias. For example...
update INVENTORY
set PRICE = (SELECT PRICE FROM INVENTORY AS [new_price] WHERE [new_price].CODE = INVENTORY.NEW_CODE)
WHERE
CODE = "SOME STOCK CODE"
UPDATE INVENTORY
SET PRICE = i_sales.PRICE
FROM INVENTORY, INVENTORY i_sales
WHERE INVENTORY.CODE LIKE 'S\_%'
AND i_sales.CODE = REPLACE(INVENTORY.Code, 'S', 'U')
This updates prices for all 'stock' records in INVENTORY with prices from the corresponding 'sales' records.
If you would prefer to update individual prices, change WHERE to something like this:
WHERE i_stock.CODE = 'S_12345'
or this:
WHERE i_stock.CODE IN ('S_12345', 'S_12346')
Note: The FROM syntax used is based on this doc page.