I have been asked to customize the formula that calculates Unit Price when using a Sales Price Worksheet. Instead of discounting on the line qty, they want to discount on the overall SO total qty.
Widget1 gets unitprice of .80 if 100 are ordered.
Widget2 gets unitprice of 1.75 if 150 are ordered.
Sales Order line 1 is for Widget1, unitqty of 200...unitprice for that line will be .80.
Sales Order line 2 is for Widget2, unitqty of 10...unitprice for that line will be 1.75 because it is based on total unit qty which equals 210 (over 150).
I cannot find the calculation code to override it. I had an idea of
/storing SOLine unitqty in OldUnitQty variable
/update SOLine untiqty to SOOrder unitqty
/call GetPriceCalculationScope
/set SOLine unitqty back to OldUnitQty
I am not sure that is a good idea or if it will even work. Can anyone give me some guidance on how to do this?
You can handle the unitqty updated event(where the header total qty will be already updated), check if total qty is more than 150 and update unit cost for the current line.
The code will be like this:
protected virtual void SOLine_OrderQty_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e, PXFieldUpdated del)
{
del?.Invoke(cache, e);
SOLine line = (SOLine)e.Row;
if (line != null)
{
if (Base.Document.OrderQty > ...)
{
line.CuryUnitPrice = ...;
}
}
}
Related
how to approach this? Change the value of unit price in the Sales line on changing its size, As far as I know the default unit price comes from trade agreements. In this case there would be no size, but for my requirement I should assign value from trade agreements for sizes 1,2,3,4 and for 5 and 6 the the value from trade agreements should be incremented with 1. i.e
For example sizes 1,2,3,4 -> 13$ and sizes 5,6 -> 14$
I am thinking to approach this making changes in the modified field method on InventSizeid in SalesTable form, is this the right approach or is there a better way to do this. Any help appreciated, thanks in advance
Check SalesTable form go to Data Sources/InventDim/Fields/InventSizeId/Methods/Modified open modified method, you need add your logic in the end of this method.
For example (this is standar method modified):
public void modified()
{
SalesCalcAvailableDlvDates salesCalcAvailableDlvDates;
super();
salesLine.modifyInventDim(inventDim, fieldNum(InventDim,InventSizeId), !salesLine.MatchingAgreementLine);
if (salesLine.DeliveryDateControlType)
{
salesCalcAvailableDlvDates = SalesCalcAvailableDlvDates::newCommonSalesDlvDateType(salesLine,0,inventDim);
salesCalcAvailableDlvDates.modifiedFieldBeforeInsert(salesLine);
}
salesLine_DS.cacheCalculateMethod(tableMethodStr(SalesLine,itemName));
//Your logic
...
...
...
SalesLine.SalesPrice = 999; //Your new sales price.
//Your logic END
}
you probably need to perform salesLine_DS.reread(); or salesLine_DS.refresh(); to see new price (else press F5 in form).
You can specify prices for product variants based on size, color etc. using the trade agreements. Please check the following link.
I have a dataset I'm working with that is buildings and electrical power use over time.
There are two aggregations on these buildings that are simple sums across the entire timespan and I have those written. They end up looking like:
var reducer = reductio();
// How much energy is used in the whole system
reducer.value("energy").sum(function (d) {
return +d.Energy;
});
These work great.
The third aggregation, however, is giving me some trouble. I need to find the point that the sum of all the buildings is at its greatest. I need the max of the sum and the time it happened.
I wrote:
reducer.value("power").sum(function (d) {
return +d.Power;
}).max(function (d) {
return +d.Power;
}).aliasProp({
time: function (d, v) {
return v.Timestamp;
}
});
But, this is not necessarily the biggest power use. I'm pretty sure this returns the sum and the time when any individual building used the most power.
So if the power values were 1, 1, 1, 15. I would end up with 18, when there might be a different moment when the values were 5, 5, 5, 5 for a total of 20. The 20 is what I need.
I am at a loss for how to get the maximum of a sum. Any advice?
Just to restate: You are grouping on time, so your group keys are time periods of some sort. What you want is to find the time period (group) for which power use is greatest.
If I'm right that this is what you want, then you would not do this in your reducer, but rather by sorting the groups. You can order groups by using the group.order method: https://github.com/crossfilter/crossfilter/wiki/API-Reference#group_order
// During group setup
group.order(function(p) { return p.power.sum; })
// Later, when you want to grab the top power group
group.top(1)
Reductio's max aggregation should just give you the maximum value that occurs within the group. So given a group with values 1,1,1,15, you would get back the value 15. It sounds like that's not what you want.
Hopefully I understood properly. If not, please comment. If you can put together an example with toy data that is public and where you can tell me what you would like to see vs what you are getting, I should be able to help out.
Update based on example:
So, what you want (based on the description in the example) is to find the maximum power usage for any given time within the selected time period. So you would do the following:
var timeDim = buildings.dimension(function(d) { return d.Timestamp })
var timeGrp = timeDim.group().reduceSum(function(d) { return d.Power })
var maxResults = timeGrp.top(1)
Whenever you want to find the max power usage time for your current filter, just call timeGrp.top(1) and the key of that group will be the time with the maximum power.
Note: Don't filter on timeDim as the filters on a dimension are not applied to groups defined on that dimension.
Here's an updated JSFiddle that writes out the maximum group to the console: https://jsfiddle.net/esjewett/1o3robm3/1/
I've been searching for similar solutions out there but am coming up short so far. Here is what I want to accomplish:
I need to come up with a basic solution to sync inventory quantities at the end of each day. We take physical counts of inventory sold throughout the day but need something to log these changes and share between users. I would like to utilize two buttons (click one to subtract amount of items sold at the end of the day and click one button to add newly received inventory).
This is how my sheet is set up:
Col A: Product Tag
Col B: Product sku
Col C: Amount Sold Today
Col D: Total Inventory Quantity
Col E: Add New Inventory
Column D will be pre-populated with initial inventory counts. At the end of each day, I would like to go down my product list and fill in the amount of each item sold that day in Column C. Once Column C is fully populated, I would like to click the "subtract" button and have Column C subtracted from Column D.
On the other side, once we receive new stock of an item I would like to enter these counts into Column E. Once this column is fully populated, I would like to click the "Add" button and have Column E added to Column D. Ideally once the add or subtract function has been completed, columns C or E will be cleared and ready for the next days entry.
I already have designed my buttons, I just need help coming up with the scripts to accomplish this.
You can use Google Apps Script for this.
If you are unfamiliar, in your particular spreadsheet, go to Tools → Script Editor and then select the Blank Project option.
Then you can write functions like this to achieve what you want!
function subtractSold() {
var sheet = SpreadsheetApp.getActiveSheet();
var c1 = sheet.getRange("C2");
var c2 = sheet.getRange("D2");
while (!c1.isBlank() && !c2.isBlank()){
c2.setValue(c2.getValue() - c1.getValue());
c1.clear();
c1 = c1.offset(1, 0);
c2 = c2.offset(1, 0);
}
}
Basically what the function does is:
Get a reference to the active spreadsheet
Get references to the cells C2 and D2, for the first row of data.
Use a while loop to repeated go through the rows. Terminate when either cell is empty.
In the loop, we get the appropriate values, subtract and set the value back into the cell. Then we clear the cell in column C. We then move both cell references down by one row (the offset method returns a reference to the original cell, but offset by row, column).
Then assign the script to the button image by entering the name of the function (subtractSold in this case) in the "Assign script" option for the button.
I have made an example sheet here (go to File → Make a Copy to try the scripts and see the code): https://docs.google.com/spreadsheets/d/1qIJdTvG0d7ttWAUEov23HY5aLhq5wgv9Tdzk531yhfU/edit?usp=sharing
A bit faster
If you try the sheet above you can see it processes one row at a time, which might get pretty slow when you have a lot of rows. It is probably faster to process the entire column in bulk, but it may be a bit more complicated to understand:
function subtractSoldBulk() {
var sheet = SpreadsheetApp.getActiveSheet();
var maxRows = sheet.getMaxRows();
var soldRange = sheet.getRange(2, 3, maxRows); // row, column, number of rows
var totalRange = sheet.getRange(2, 4, maxRows);
var soldValues = soldRange.getValues();
var totalValues = totalRange.getValues();
for (var row in soldValues) {
var soldCellData = soldValues[row][0];
var totalCellData = totalValues[row][0];
if (soldCellData != "" && totalCellData != "") {
totalValues[row][0] = totalCellData - soldCellData;
soldValues[row][0] = "";
}
}
soldRange.setValues(soldValues);
totalRange.setValues(totalValues);
}
The difference here is that instead of getting one cell, we get one range of cells. The getValues() method then gives us a 2D array of the data in that range. We do the calculations on the two arrays, update the data in the arrays, and then set the values of the ranges based on the array data.
You can find documentation for the methods used above from Google's documentation: https://developers.google.com/apps-script/reference/spreadsheet/sheet
My Column Having Value Like 1000EUR, 2000INR, 3000USD.I want to show the sum of Amount at footer of the gridview.
How Should i Calculate this total amount at the bottom of the column?
Any way to remove the Alphabets and Summ the Amount? In Usual ASPxSummaryItem Its Calculating as 0.
My Code:
<dxwgv:ASPxSummaryItem FieldName="CommissionAmount" SummaryType="Sum" DisplayFormat="Total Commission Amount = {0} " />
What is the sum supposed to be? obviously not 6000.
The summary type you're using should be custom.
<dxwgv:ASPxSummaryItem FieldName="CommissionAmount" SummaryType="Custom" DisplayFormat="Total Commission Amount = {0} " />
Then, add event handler for ASPxGridView1_CustomSummaryCalculate and add the code behind to do the conversion and summing such:
protected void ASPxGridView1_CustomSummaryCalculate(object sender, DevExpress.Data.CustomSummaryEventArgs e)
{
e.TotalValue = 1000 + 2000 * USD2EUR + 300 * INR2EUR;
}
I am building an e-store and I need to have the ability to add fractional quantities to the shopping cart.
Admin would set a denominator per product (e.g. 8 would mean that the minimum purchase is 1/8 of a case)
I currently use a jQuery slider and display the quantity in the asp:Label which works just fine on product pages, however it gets out of hand with multiple sliders in the cart (I need to allow the customer to adjust quantities in the cart).
I really want to stay away from ugly dropdown lists.
Any ideas?
EDIT:
Fixed denominator is out of the question ... 4/8 have to show as 1/2 ...
EDIT2:
Usability is important too, + 1/denominator increment per click won't work too well when a customer wants to go from 1/16th of a case to 3 cases
EDIT3:
#RichB: adding a SKU for a fraction of a case goes back to fixed denominator problem. if i add a SKU for 1/16th of a case, and a user wants 1/2 of a case, they would have to order 8x1/16th's [not cool]. If you want to add a SKU for every possible fraction (15 SKUs in this example - this will make my Product page and the CART way to cluttered.
One way would be for you to have your quantity textbox followed by a " / [denominator]" string that would allow them to say something like [4] / 8 to designate half a case of 8.
Your only problem there is you're going to having a simple method to keep track of what those denominators are.
Another possible solution (since you are against having a fixed denominator), is to use a series of Up/Down arrows/buttons/whatever and you can use the up and down to increment or decrement the amount of product (and on each increment/decrement correctly update the fractional value in the label).
Edit: This could be further refined by adding in a separate increment/decrement button to modify the quantity by a whole case instead of by a single fractional amount.
I would have a single field, which can be edited to a quantity like 3 6/4. However, when the field looses focus, this will be converted to simplest mixed fraction (4 1/2 for my example).
This allows flexibility of input as well as nice number formatting.
Update: OP says "that's EXACTLY what i'm using right now, however when i get to CART [and have 10 items in the cart] managing multiple sliders becomes problematic. that's why i'm looking for an alternative solution"
Would something like the following work?
See it working here. (edit it here)
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<link rel="stylesheet" href="http://jquery-ui.googlecode.com/svn/tags/1.7/themes/base/ui.all.css" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7/jquery-ui.min.js"></script>
<div class="demo">
<p>
<label for="amount">amount :</label>
<input type="text" id="amount" />
</p>
<div id="slider"></div>
</div>
var maxDenominator = 16;
var maxWholeCases = 50;
function toFraction(sliderValue){
var amount = sliderValue / maxDenominator;
var whole = Math.floor(amount);
var fractional = "";
if (amount - whole)
fractional = fractApprox(amount - whole, maxDenominator);
return whole + " " + fractional + " cases";
}
$(function() {
$("#slider").slider({
value:10 * maxDenominator,
min: 0,
max: maxWholeCases * maxDenominator,
slide: function(event, ui) {
$("#amount").val(toFraction(ui.value));
}
});
$("#amount").val(toFraction($("#slider").slider("value")));
});
// from http://www.geneffects.com/briarskin/programming/newJSMathFuncs.html#fractApprox
function fractApprox(x,maxDenominator) {
// Created 1997 by Brian Risk. http://brianrisk.com
maxDenominator = parseInt(maxDenominator);
var approx = 0;
var error = 0;
var best = 0;
var besterror = 0;
for (var i=1; i <= maxDenominator; i++) {
approx = Math.round(x/(1/i));
error = (x - (approx/i))
if (i==1) {best = i; besterror = error;}
if (Math.abs(error) < Math.abs(besterror))
{best = i; besterror = error;}
}
return (Math.round(x/(1/best)) + "/" + best);
}
I ended up linking a product page to quantities in cart, so users can update the fractions with the slider on the product page.
I'd stay away from using fractional units. Instead try something like this.
[ _ _ _ ] cases [ _ _ _ ] individual units
Use 2 SKUs, 1 for a case, and 1 for an individual unit.
Or define a split as a fraction of a case, with product.quantity_per_case.
When I ran restaurants, I'd order like this all of the time. It requires almost no thinking, as you're not dealing with fractions, but whole numbers of cases and whole numbers of units.
Most people will need either cases or splits, but not both.