Calculated Field on CRM Entity - dynamics-crm-2011

I have a 1:N relationship between Account and Portfolios in Dynamics CRM
I.e each account has multiple Portfolios and Each Portfolio has Specific Assets.
I am trying to create a field on Account Form which calculates the sum of "ALL Assets of All related portfolios" of the account and display it on the Account form
As a workaround,I tried to create a Portfolio view grouping by Account but it doesnt SUM and rollup the Portfolio assets to Account level.
So on account Form i am trying to create a textfield which calculates the Total Account Assets to be $25,000 in this example

function setupGridRefresh() {
var targetgrid = document.getElementById("NAME OF SUBGRID");
// If already loaded
if (targetgrid.readyState == 'complete') {
targetgrid.attachEvent("onrefresh", subGridOnload);
}
else {
targetgrid.onreadystatechange = function applyRefreshEvent() {
var targetgrid = document.getElementById("NAME OF SUBGRID");
if (targetgrid.readyState == 'complete') {
targetgrid.attachEvent("onrefresh", subGridOnload);
}
}
}
subGridOnload();
}
function subGridOnload() {
//debugger;
var grid = Xrm.Page.ui.controls.get('NAME OF SUBGRID')._control;
var sum = 0.00;
if (grid.get_innerControl() == null) {
setTimeout(subGridOnload, 1000);
return;
}
else if (grid.get_innerControl()._element.innerText.search("Loading") != -1) {
setTimeout(subGridOnload, 1000);
return;
}
var ids = grid.get_innerControl().get_allRecordIds();
var cellValue;
for (i = 0; i < ids.length; i++) {
if (grid.get_innerControl().getCellValue('FIELD NAME LOWER CASE', ids[i]) != "") {
cellValue = grid.get_innerControl().getCellValue('FIELD NAME LOWER CASE', ids[i]);
cellValue = cellValue.substring(2);
cellValue = parseFloat(cellValue);
sum = sum + cellValue;
}
}
var currentSum = Xrm.Page.getAttribute('DESTINATION FIELD').getValue();
if (sum > 0 || (currentSum != sum && currentSum != null)) {
Xrm.Page.getAttribute('DESTINATION FIELD').setValue(sum);
}
}
I pieced this together from a couple of sources and currently use it one of my solutions. Let me know if you need some more help or if I've misread the question. (Btw, this solution is based on the assumption that you need the total to change when the subgrid has entries added or removed. If this is not the requirement, I would suggest the RetrieveMultiple OData call.)

Take a look at AutoSummary from Gap Consulting, well worth the cost. Or spend time to build your own. You need a field on the Account record which is updated every time you:
create a Portfolio record
update the value in a Portfolio record
delete a Portfolio record
re-parent a Partfolio record from one Account to another
The first two are easy enough to do with workflow or javascript on the onSave event on the portfolio. Third can only be done by workflow, not javascript (I think). Last one would need onLoad javascript to store current value of Account lookup so that onSave can compare and then decrement one and increment the other. All four could be done with a plugin.

Although this has been answered already, I'll put a second option on the plate for you. Take a look at FormulaManager from North 52 as well. You get a certain amount of Formulas for free so it might be an even more cost effective solution.
Update
To add to this, if the field is solely for reporting a value (and doesn't need to be saved to the database) then rather than using a physical field and plugins you could build a Web Resource that executes an Aggregated FetchXml query and simply displays the resulting value.
Again, this is something that I know Formula Manager does out of the box. Have never used Auto Summary.

Related

Select parts of a nlobjSearchResult

I have a large nlobjSearchResultSet object with over 18,000 "results".
Each result is a pricing record for a customer. There may be multiple records for a single customer.
As 18000+ records is costly in governance points to do mass changes, I'm migrating to a parent (customer) record and child records (items) so I can make changes to the item pricing as a sublist.
As part of this migration, is there a simple command to select only the nlapiSearchResult objects within the big object, which match certain criteria (ie. the customer id).
This would allow me to migrate the data with only the one search, then only subsequent create/saves of the new record format.
IN a related manner, is there a simple function call to return to number of records contained in a given netsuite record? For % progress context.
Thanks in advance.
you can actually get the number of rows by running the search with an added aggregate column. A generic way to do this for a saved search that doesn't have any aggregate columns is shown below:
var res = nlapiSearchRecord('salesorder', 'customsearch29', null,
[new nlobjSearchColumn('formulanumeric', null, 'sum').setFormula('1')]);
var rowCount = res[0].getValue('formulanumeric', null, 'sum');
console.log(rowCount);
To get the total number of records, the only way is do a saved search, an ideal way to do such search is using nlobjSearch
Below is a sample code for getting infinite search Results and number of records
var search = nlapiLoadSearch(null, SAVED_SEARCH_ID).runSearch();
var res = [],
currentRes;
var i = 0;
while(i % 1000 === 0){
currentRes = (search.getResults(i, i+1000) || []);
res = res.concat(currentRes );
i = i + currentRes.length;
}
res.length or i will give you the total number of records and res will give you all the results.

Highlight Duplicate list item in SharePoint 2013

I have a SharePoint 2013 (The Cloud version) custom list where 1 column is a text field where contact numbers are keyed in.
How can I get SharePoint to highlight duplicate values in that column so that every time a new item is added to the list, I'll know if the contact number has been used previously?
Ideally, here's what I'd get if I were to enter 816's details for the 2nd time:
CNO....Name.......Issue
816.....Blink........Login Problem (highlighted in red)
907.....Sink.........Access Denied
204.....Mink.........Flickering Screen
816.....Blink........Blank Screen (highlighted in red)
I've been struggling with this for awhile and would be very grateful for any advice. Thanks!
Since SharePoint 2013 uses Client Side Rendering (CSR) as a default rendering mode I would recommend the following approach. Basically the idea is to customize List View on the client side as demonstrated below.
Assume the Requests list that contains RequestNo column.
The following JavaScript template is intended for highlighting the rows when list item with RequestNo column occurs more then once:
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPostRender: function(ctx) {
var rows = ctx.ListData.Row;
var counts = getItemCount(rows,'RequestNo'); //get items count
for (var i=0;i<rows.length;i++)
{
var count = counts[rows[i]["RequestNo"]];
if (count > 1)
{
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
tr.style.backgroundColor = "#ada";
}
}
}
});
function getItemCount(items,propertyName)
{
var result = {};
for(var i = 0; i< items.length; i++) {
var groupKey = items[i][propertyName];
result[groupKey] = result[groupKey] ? result[groupKey] + 1 : 1;
}
return result;
}
How to apply the changes
Option 1:
Below is demonstrated probably one of easiest way how to apply those changes:
Open the page in Edit mode
Add Content Editor or Script Editor web part on the page
Insert the specified JavaScript template by enclosing it using
script tag into web part
Option 2:
Save the specified JavaScript template as a file (let's name it duplicatehighlight.js) and upload it into Site Assets library
Open the page in Edit mode and find JSLink property in List View web part
Specify the value: ~sitecollection/SiteAssets/duplicatehighlight.js and save the changes.
Result
SharePoint has some basic conditional formatting for Data View Web Parts and XSLT List Views, but the conditions you can use are rather limited. You can compare a field in the current item with a value that you specify. There are no formulas to count the number of items with the same name or similar, which would be the approach to use to identify duplicates.
If you need to identify duplicates, you may want to create a view that groups by the CNO number. Grouping will also include an item count, so you can run down the list and spot groups with more than one item.

Recurring Events in SharePoint - Incorrect "Duration"

Background:
The company I work for has a regular SharePoint list with a custom ContentType (that does not inherit from a calendar list item) that it uses for Events. It then shows these using a calendar view. Seems simple enough.
We have the need to allow the user to choose a timezone for the event (different from their regional setting) that they are adding and to add the information to sharepoint such that it will show the correct time for each user looking at it world wide (based on their regional setting of course).
I added a list to SharePoint that is used to lookup SystemTimeZones (basically a SharePoint List representation of TimeZoneInfo.GetSystemTimeZones())
SPList timeZonesList = thisWeb.Lists.TryGetList("SystemTimeZones");
if(timeZonesList == null)
{
string title = "SystemTimeZones";
string description = "SharePoint List representation of TimeZoneInfo.GetSystemTimeZones() used for lookup.";
Guid newListId = thisWeb.Lists.Add(title, description, SPListTemplateType.GenericList);
timeZonesList = thisWeb.Lists.GetList(newListId, true);
timeZonesList.Fields.Add("SystemTimeZoneId", SPFieldType.Text, true);
timeZonesList.Fields.Add("SystemTimeZoneName", SPFieldType.Text, true);
SPView defaultTimeZonesView = timeZonesList.DefaultView;
defaultTimeZonesView.ViewFields.Add("SystemTimeZoneId");
defaultTimeZonesView.ViewFields.Add("SystemTimeZoneName");
defaultTimeZonesView.Update();
foreach (TimeZoneInfo timeZone in TimeZoneInfo.GetSystemTimeZones())
{
SPListItem temp = timeZonesList.AddItem();
temp["SystemTimeZoneId"] = timeZone.Id;
temp["SystemTimeZoneName"] = timeZone.DisplayName;
temp.Update();
}
}
I'm using this list for the lookup item for EventTimeZone in my custom add and edit forms for this list. The forms are direct copies of what SharePoint Designer would create (in that they are using the SharePoint:FormField's) they are just in Visual Studio bc I needed code-behind. I wanted to allow the users to see the events in their Regional TimeZone however when they edit them I wanted to show them in the TimeZone they were entered. (IE my regional timezone is Central so when I look at a Mountain meeting it will show me 10-11am but when I edit that same meeting it will say it is 9-10am). So on page load of edit I adjust the times:
SPListItem thisEvent = eventsList.GetItemById(savebutton1.ItemId);
if (thisEvent != null)
{
bool isAllDayEvent = false;
if (thisEvent["fAllDayEvent"] != null)
{
isAllDayEvent = (bool)thisEvent["fAllDayEvent"];
}
if (!isAllDayEvent)
{
SPFieldLookupValue lookupValue = new SPFieldLookupValue(thisEvent["Event Time Zone"].ToString());
TimeZoneInfo eventTimeZone = GetEventTimeZoneByListItemId(lookupValue.LookupId, rootWeb);
SPTimeZone regionalTimeZone = GetRegionalTimeZone(rootWeb);
DateTime regionalStartDateTime = Convert.ToDateTime(thisEvent["StartDate"]);
DateTime originalStartDateTime = TimeZoneInfo.ConvertTimeFromUtc(regionalTimeZone.LocalTimeToUTC(regionalStartDateTime), eventTimeZone);
ff3.ListItemFieldValue = originalStartDateTime;
DateTime regionalEndDateTime = Convert.ToDateTime(thisEvent["EndDate"]);
DateTime originalEndDateTime = TimeZoneInfo.ConvertTimeFromUtc(regionalTimeZone.LocalTimeToUTC(regionalEndDateTime), eventTimeZone);
ff4.ListItemFieldValue = originalEndDateTime;
}
else
{
// for some reason with all day events, sharepoint saves them
// as the previous day 6pm. but when they show up to any user
// they will show as 12am to 1159pm and show up correctly on the calendar
// HOWEVER, when it comes to edit, the start date isn't corrected on the
// form, so continuing to save without fixing it will continue to decrease
// the start date/time by one day
DateTime regionalStartDateTime = Convert.ToDateTime(thisEvent["StartDate"]);
ff3.ListItemFieldValue = regionalStartDateTime.AddDays(1);
}
All day events were strange but I was able to make it work by just writing test cases and see what happened (as you can see from my comments).
Then I tie into the list event receivers ItemAdded and ItemUpdated to "fix" the times since SharePoint is going to save them based on the user's regional setting and not the timezone the user chose. (Of course I'm slightly new to SharePoint -- not c# -- so I may have very much over complicated this, but I have been able to fine little documentation online). In the end I end up setting:
addedItem["StartDate"] = regionalTimeZone.UTCToLocalTime(correctedEventStart.ToUniversalTime());
addedItem["EndDate"] = regionalTimeZone.UTCToLocalTime(correctedEventEnd.ToUniversalTime()); TADA!! It saves and display perfectly! I was so excited! Until... I tried to save a recurring event. All of my recurring events save wonderfully, it's not the recurring part that's messed up. For some reason, after I change the StartDate and EndDate on a recurring event and call addedItem.Update() it is recalculating the "Duration" as if it is a single even instead of a recurring event. Example: I have an event that happens for a week daily from 9-10. When I first enter ItemAdded my Duration is 3600 (1 hour) as it should be bc Duration is treated differently for recurring events. However after I adjust the times and call Update() the duration spans the entire week :( If I manually set the Duration:
if (isRecurrence)
{
addedItem["Duration"] = (correctedEventEnd.TimeOfDay - correctedEventStart.TimeOfDay).TotalSeconds;
}
It still gets reset on Update(). So when you view the recurring item in a Calendar View the item spans the entire week instead of showing once a day.
I have all but pulled my hair out trying to figure this out. Any guidance would be wonderful. I understand Duration is a calculated field but I can't understand why calling listItem.Update() would ignore the fact that it is indeed properly marked as a recurring event and not calculate the Duration correctly. This honestly seems like a bug with SP 2010.
Thanks in advance!
**
EDIT: Additional info after comments below...
**
This SharePoint env has a server in pacific time and users across all US TimeZones, London, Tokyo, Abu Dabi, etc. Users in one timezone need to be able to create events in other timezones. Since nothing in the user's profile (for us anyway) will tell us what timezone they would like to see everything in, we added code to our master page to look at the local machine's timezone and always set their regional setting accordingly.
Example: I am in Nashville and I want to create an event that will happen in LA:
The data in ItemAdded shows that StartDate is what I entered 9am. So I'm creating a date that has PST at the end of it:
DateTime correctedEventStart = DateTime.Parse(addedItem["StartDate"] + " " + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Hours + ":" + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Minutes);
DateTime correctedEventEnd = DateTime.Parse(addedItem["EndDate"] + " " + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Hours + ":" + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Minutes);
Then to "trick" SharePoint I'm converting that PST time into the users regional time (so the user doesn't have to know anything about their regional setting nor do they have to think). So 9am PST is 7am CST (bc that's what SharePoint expects the time to be in since that's my regional setting). Here's the converstion from the correct time+timezone to the user regional timezone:
addedItem["StartDate"] = regionalTimeZone.UTCToLocalTime(correctedEventStart.ToUniversalTime());
addedItem["EndDate"] = regionalTimeZone.UTCToLocalTime(correctedEventEnd.ToUniversalTime());
I don't know if this makes sense to anyone outside of my world. But SharePoint obviously expects the times to be in the user's regional (or the web's) timezone. That's obvious my from unit testing. If there is an OOB way for me to allow a user in Central Time to create a meeting from 9-10am Pacific Time in a custom list I would LOVE to be able to use that. But I haven't been able to find anything.
Again, all of this works great... until you come to Recurring Events. And actually it works for recurring events until you try to view said event in a Calendar View. Then it looks like this:
Notice that "Recurring 8" is recurring the way it's supposed to, daily for 2 instances. However, the "span" or "duration" of the recurrence is 2 days rather than 1 hour. Where as "Recurring 15" shows correctly. The only difference in field values between the two when output to debug is the "Duration" field. Recurring 8 had it's start and end date's updated in ItemAdded and Recurring 15 went through ItemAdded but the ListItem.Update() was commented out. Per documentation SharePoint is supposed to calculate Duration differently for recurring items than it does for single items. The fact that the start and end dates are changed using the object model should not negate that.
Ok, so the way I ended up handling this is as follows. I decided to back out of the list event receiver because it really does appear to be a SharePoint bug in the recalculation of Duration for recurring events now working correctly. I opted to tie into the save event on the form and changing the values before they are even sent. This seems to work so far in all scenarios. All of my math is the same as before. So in my New2.aspx (new item form for this list)
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if ((SPContext.Current.FormContext.FormMode == SPControlMode.New) || (SPContext.Current.FormContext.FormMode == SPControlMode.Edit))
{
SPContext.Current.FormContext.OnSaveHandler += new EventHandler(SaveHandler);
}
}
protected void SaveHandler(object sender, EventArgs e)
{
Page.Validate();
if (Page.IsValid)
{
// fix times
SPFieldLookupValue lookupValue = new SPFieldLookupValue(ff5.Value.ToString());
TimeZoneInfo eventTimeZone = GetEventTimeZoneByListItemId(lookupValue.LookupId, SPContext.Current.Web);
SPTimeZone regionalTimeZone = GetRegionalTimeZone(SPContext.Current.Web);
bool isAllDayEvent = Convert.ToBoolean(ff6.Value);
bool isRecurrence = Convert.ToBoolean(ff11.Value);
DateTime correctedEventStart = DateTime.MinValue;
DateTime correctedEventEnd = DateTime.MinValue;
if (!isAllDayEvent && eventTimeZone != null && regionalTimeZone != null)
{
correctedEventStart = DateTime.Parse(ff3.Value.ToString() + " " + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Hours + ":" + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Minutes);
correctedEventEnd = DateTime.Parse(ff4.Value.ToString() + " " + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Hours + ":" + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Minutes);
ff3.ItemFieldValue = regionalTimeZone.UTCToLocalTime(correctedEventStart.ToUniversalTime());
ff4.ItemFieldValue = regionalTimeZone.UTCToLocalTime(correctedEventEnd.ToUniversalTime());
}
SPContext.Current.ListItem.Update();
}
}
This updates the times as my previous approach does but it will also calculate the duration correctly.
SharePoint handles displaying the correct time based on the user's regional settings (or web if the user hasn't set it) and displaying the correct times in calendar views. I did have to change the Edit form to have the correct values on edit:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
try
{
using (SPWeb rootWeb = SPContext.Current.Site.RootWeb)
{
SPList eventsList = rootWeb.Lists.TryGetList("Events");
if (eventsList != null)
{
SPListItem thisEvent = eventsList.GetItemById(savebutton1.ItemId);
if (thisEvent != null)
{
bool isAllDayEvent = false;
if (thisEvent["fAllDayEvent"] != null)
{
isAllDayEvent = (bool)thisEvent["fAllDayEvent"];
}
if (!isAllDayEvent)
{
SPFieldLookupValue lookupValue = new SPFieldLookupValue(thisEvent["Event Time Zone"].ToString());
TimeZoneInfo eventTimeZone = GetEventTimeZoneByListItemId(lookupValue.LookupId, rootWeb);
SPTimeZone regionalTimeZone = GetRegionalTimeZone(rootWeb);
DateTime regionalStartDateTime = Convert.ToDateTime(thisEvent["StartDate"]);
DateTime originalStartDateTime = TimeZoneInfo.ConvertTimeFromUtc(regionalTimeZone.LocalTimeToUTC(regionalStartDateTime), eventTimeZone);
ff3.ListItemFieldValue = originalStartDateTime;
DateTime regionalEndDateTime = Convert.ToDateTime(thisEvent["EndDate"]);
DateTime originalEndDateTime = TimeZoneInfo.ConvertTimeFromUtc(regionalTimeZone.LocalTimeToUTC(regionalEndDateTime), eventTimeZone);
ff4.ListItemFieldValue = originalEndDateTime;
}
else
{
// for some reason with all day events, sharepoint saves them
// as the previous day 6pm. but when they show up to any user
// they will show as 12am to 1159pm and show up correctly on the calendar
// HOWEVER, when it comes to edit, the start date isn't corrected on the
// form, so continuing to save without fixing it will continue to decrease
// the start date/time by one day
DateTime regionalStartDateTime = Convert.ToDateTime(thisEvent["StartDate"]);
ff3.ListItemFieldValue = regionalStartDateTime.AddDays(1);
}
}
}
}
}
catch (Exception ex)
{
DebugLogger.WriteLine(ex);
}
}
}
The Edit form has the same OnInit and SaveHandler as New.
I think you are running afoul of the shennagins that SharePoint uses for reccuring events. Essentially the events are stored in a single list item and expanded at query time. This makes the storage of events quite counter intuitive to how you expect.
From that post it looks like the EventDate and EndDate fields are used differently depending on the recurrence or not.
Also be aware the SharePoint stores dates in UTC 'under the hood' and converts back to the users (or websites) timezone on display. You may be able to use this knowledge to optimise some of the date logic.
More information
http://fatalfrenchy.wordpress.com/2010/07/16/sharepoint-recurrence-data-schema/
Share point 2010 ItemAdding insert Recurrence data on calendar
http://blog.tylerholmes.com/2012/02/how-sharepoint-deals-with-time-and-time.html
Here is the code I used to create an occuring event in another timezone (note: I did not explicitly set the duration)
public void AddRecurringItemGTM8Perth(SPList list)
{
string recData = "<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><daily dayFrequency=\"1\" /></repeat><windowEnd>2013-02-20T01:00:00Z</windowEnd></rule></recurrence>";
SPListItem newitem = list.Items.Add();
newitem["Title"] = "Perth " + DateTime.Now.ToString();
newitem["RecurrenceData"] = recData;
newitem["EventType"] = 1;
DateTime correctedEventStart = new DateTime(2013, 2, 3, 12, 0, 0);
//note that date is end of event and time is event end to calculate duration
DateTime correctedEventEnd = new DateTime(2013, 2, 20, 13, 0, 0);
SPTimeZone spTz = SPRegionalSettings.GlobalTimeZones[74]; //perth
correctedEventStart = spTz.LocalTimeToUTC(correctedEventStart);
correctedEventEnd = spTz.LocalTimeToUTC(correctedEventEnd);
correctedEventStart = list.ParentWeb.RegionalSettings.TimeZone.UTCToLocalTime(correctedEventStart);
correctedEventEnd = list.ParentWeb.RegionalSettings.TimeZone.UTCToLocalTime(correctedEventEnd);
newitem["Start Time"] = correctedEventStart;
newitem["End Time"] = correctedEventEnd;
newitem["Recurrence"] = true;
newitem["fAllDayEvent"] = false;
newitem["WorkspaceLink"] = false;
newitem["UID"] = Guid.NewGuid();
newitem.Update();
list.Update();
}
So I convert from users "local" to UTC and then back to the web local.
The UID is necessary or there is an error when you click on the event.
If you want a recurrence of 13 say... the code is:
string recData = "<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><daily dayFrequency=\"1\" /></repeat><repeatInstances>13</repeatInstances></rule></recurrence>";
DateTime correctedEventEnd = new DateTime(2013, 2, 3, 13, 0, 0).AddDays(13);
Whereas no end date is :
string recData = "<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><daily dayFrequency=\"1\" /></repeat><repeatForever>FALSE</repeatForever></rule></recurrence>";
DateTime correctedEventEnd = new DateTime(2013, 2, 3, 13, 0, 0).AddDays(998);
It might be quite old, but my answer may help someone.
You just have to explicitly put EventType = 1 in update as well.

SharePoint 2010 - Need suggestion

I have one datasheet like mentioned below
WorkWeek Person1 Person2
WW1 X Y
WW2 Z A
WW3 X Z
Where A,X,Y & Z are members of the sharepoint group.
Required I want display a webpart like this
WW1
Image1 Image2
X Y
Next Week the webpart should get updated like this dynamically.
WW2
Image3 Image4
Z A
Where this requirement is possible, If possible then pls suggest how to accomplish this.
I can provide you some Logic which may help you to accomplish this requirement.
Create one Visual web part with the user control which has html as per your requirement,
To get the data from the datasheet use the Code to read the data from Data sheet
When you want to display the data for the First week create one varible and maintain it to identify the sequence of week to get from datasheet.
First time When you access the datasheet set this varibale with your week of year number.
Condition the reading of datasheet with this variable like IF variable is null then assign it the week no of year.,
Check this variable next time you come to this logic that If variable is less than the week no current week no of year then take datasheet last you get + 1 means Datasheet 2 and so on
..
Sorry for bad english
variable : one for DaasheetNo, WeekNo,CurrentWeekNo
assign datasheetNo = Sheet1
If(WeekNo== Null)
{
first time getdata from DaasheetNo (First Sheet)
}
else if(WeekNo < CurrentWeekNo)
{
Get data from datasheetNo +1
}
Hope it helps you
This is called weekly update Webpart in SharePoint.
My Idea:
you can set one CurrentDate value like DateTime.Today to Current Web properties.also set one more properties which WorkWeek users. now check
SPWeb web = SPContext.Current.Web;
if (string.isnullorEmpty(web.Properties["CurrentDate"]))
{
web.Properties["CurrentDate"] = DateTime.Today.Tostring();
// do the stuff for displying data.
}
else
{
if(IFChangeNeeded())
{
// do the stuff for displying data.
}
else
{
web.Properties["CurrentDate"] = DateTime.Today.Tostring();
// do the stuff for displying data.
}
}
IfChangeNeeded() is function which return bool value. this function check that employee need to change on this week.
public bool IFChangeNeeded()
{
DateTime PropDate = Convert.ToDateTime(web.Properties["CurrentDate"]);
DateTime TDate = DateTime.Today;
if(WeekNo(TDate) == WeekNo(PropDate)) // WeekNo is function return weekno from current date.
{
return true;
}
else
{
return false;
}
}

Magento upfront payment

For a future project we have been assigned to create a simple concept (inside Magento) that would has to do the following:
A customer has the ability to choose between different shipping methods, one of them being "Ship2Shop", which sends the product to a physical store of choice and the customer has to go an pick it up.
When a customer selects this "ship2shop" shipping method, a certain percentage (eg: 25%) of the total amount has to be paid online (via a pre-defined payment method) and the remaining 75% has to be paid in the physical store when the customer goes and pick up the products he ordered.
How would you go about this?
Idea that we were having is modify the checkout/order session and modify the "grand total" amount (saving the original in a session ofcourse). When the customer is then sent to the external payment processor the "modified grand total" is sent along. Once the customer returns on the magento platform we would modify the order by restoring the original grand total the way it was and updating the total paid and total due amount.
Anyone got any other ideas about this?
EDIT:
After feedback from Anton S below I managed to add an "advance payment total". However Im still having a problem
In the config.xml I have added the following in the tag:
acsystems_advancepayment/total_custom
grand_total
I want my advance payment to show AFTER the grand total, for some reason, magento won't do that...
EDIT2: Collect method
public function collect(Mage_Sales_Model_Quote_Address $address)
{
parent::collect($address);
$quote = $address->getQuote();
$advancePaymentAmount = 0;
$baseAdvancePaymentAmount = 0;
$items = $address->getAllItems();
if (!count($items)) {
$address->setAdvancePaymentAmount($advancePaymentAmount);
$address->setBaseAdvancePaymentAmount($baseAdvancePaymentAmount);
return $this;
}
$address->setBaseAdvancePayment($address->getGrandTotal()*(0.25));
$address->setAdvancePayment($address->getGrandTotal()*(0.25));
$address->setAdvancePaymentAmount($address->getGrandTotal()*(0.25));
$address->setBaseAdvancePaymentAmount($address->getGrandTotal()*(0.25));
$address->setGrandTotal($address->getGrandTotal() - $address->getAdvancePaymentAmount());
$address->setBaseGrandTotal($address->getBaseGrandTotal()-$address->getBaseAdvancePaymentAmount());
return $this;
}
refer to this thread where adding total objects is explained Magento: adding duties/taxes to a quote during review
Basically you should add your own total object based on your shipping method selection, then it will also be shown in totals as separate row and you can show this in every e-mail or place where totals are exposed
public function collect(Mage_Sales_Model_Quote_Address $address)
{
//this is for the loop that you are in when totals are collected
parent::collect($address);
$quote = $address->getQuote();
//variables for your own object context
$advancePaymentAmount = 0;
$baseAdvancePaymentAmount = 0;
$items = $address->getAllItems();
if (!count($items)) {
$address->setAdvancePaymentAmount($advancePaymentAmount);
$address->setBaseAdvancePaymentAmount($baseAdvancePaymentAmount);
return $this;
}
//calculated based on other total object and don't edit other totals inside your own as your calculations would be always false and so would be next total object in the cycle and so on
$baseAdvancePaymentAmount = $address->getBaseGrandTotal()*(0.25);
$advancePaymentAmount = $address->getQuote()->getStore()->convertPrice($baseAdvancePaymentAmount, false);
//this is just for your own object context
$address->setBaseAdvancePaymentAmount($baseAdvancePaymentAmount);
$address->setAdvancePaymentAmount($advancePaymentAmount);
/*
* this is for the loop that you are in when totals are collected and
* those are set to 0 for each totals collecting cycle
*/
$this->_setBaseAmount($baseAdvancePaymentAmount);
$this->_setAmount($advancePaymentAmount);
return $this;
}
Another option is to change the "grand_total" in your payment module, that way the sessions aren't altered..

Resources