function ifstatement() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("Product Form");
const ws2 = ss.getSheetByName("Email details");
var Avals = ws.getRange("c1:c").getValues();
var lr = Avals.filter(String).length;
Logger.log(lr);
var recipient = ws.getRange(lr,2).getValue();
var sub = ws.getRange(lr,4).getValue();
var mailTemp = ws.getRange(lr,5).getValue();
var impfield1 = ws.getRange(lr,6).getValue();
var impfield2 = ws.getRange(lr,8).getValue();
var impfield3 = ws.getRange(lr,10).getValue();
var fieldvalue1 = ws.getRange(lr,7).getValue();
var fieldvalue2 = ws.getRange(lr,9).getValue();
var fieldvalue3 = ws.getRange(lr,11).getValue();
var heading = ws.getRange(lr,12).getValue();
var subheading = ws.getRange(lr,13).getValue();
var body = ws.getRange(lr,14).getValue();
var footer = ws.getRange(lr,15).getValue();
var attach = ws.getRange(lr,17).getValue();
var tomail = ws.getRange(lr,16).getValue();
var file1 = attach.split(",").map(url => DriveApp.getFileById(url.trim().split("=")[1]).getBlob());
var AvalsWealth = ws2.getRange("b1:b").getValues();
var AvalsInsurance = ws2.getRange("c1:c").getValues();
var AvalsTeam = ws2.getRange("e1:e").getValues();
var lrWealth = AvalsWealth.filter(String).length;
var lrInsurance = AvalsInsurance.filter(String).length;
var lrTeam = AvalsTeam.filter(String).length;
Logger.log(mailTemp);
Logger.log(heading);
if(tomail=="Wealth RMs"){
var bccmail = ws2.getRange(2,2,lrWealth).getValues().toString();
} else if(tomail=="Self"){
var bccmail = recipient;
} else if(tomail=="Insurance RMs"){
var bccmail = ws2.getRange(2,3,lrInsurance).getValues().toString();
} else if(tomail=="All India"){
var bccmail = ws2.getRange(2,4,lrTeam).getValues().toString();
}
Logger.log(bccmail)
if(mailTemp=="HTML1"){
const htmlTemplate = HtmlService.createTemplateFromFile("HTML1");
htmlTemplate.heading = heading;
htmlTemplate.subheading = subheading;
htmlTemplate.body = body;
htmlTemplate.footer = footer;
htmlTemplate.impfield1 = impfield1;
htmlTemplate.impfield2 = impfield2;
htmlTemplate.impfield3 = impfield3;
htmlTemplate.fieldvalue1 = fieldvalue1;
htmlTemplate.fieldvalue2 = fieldvalue2;
htmlTemplate.fieldvalue3 = fieldvalue3;
const htmlforemail = htmlTemplate.evaluate().getContent();
GmailApp.sendEmail('',
""+ sub + "",
'',
{htmlBody: htmlforemail,
bcc: bccmail,
attachments: file1}
) } else if(mailTemp=="HTML2"){
const htmlTemplate = HtmlService.createTemplateFromFile("HTML2");
htmlTemplate.heading = heading;
htmlTemplate.subheading = subheading;
htmlTemplate.body = body;
htmlTemplate.footer = footer;
htmlTemplate.impfield1 = impfield1;
htmlTemplate.impfield2 = impfield2;
htmlTemplate.impfield3 = impfield3;
htmlTemplate.fieldvalue1 = fieldvalue1;
htmlTemplate.fieldvalue2 = fieldvalue2;
htmlTemplate.fieldvalue3 = fieldvalue3;
const htmlforemail = htmlTemplate.evaluate().getContent();
GmailApp.sendEmail('',
""+ sub + "",
'',
{htmlBody: htmlforemail,
bcc: bccmail,
attachments: file1}
) } else if(mailTemp=="HTML3"){
const htmlTemplate = HtmlService.createTemplateFromFile("AUM Annual awards");
htmlTemplate.heading = heading;
htmlTemplate.subheading = subheading;
htmlTemplate.body = body;
htmlTemplate.footer = footer;
htmlTemplate.impfield1 = impfield1;
htmlTemplate.impfield2 = impfield2;
htmlTemplate.impfield3 = impfield3;
htmlTemplate.fieldvalue1 = fieldvalue1;
htmlTemplate.fieldvalue2 = fieldvalue2;
htmlTemplate.fieldvalue3 = fieldvalue3;
const htmlforemail = htmlTemplate.evaluate().getContent();
GmailApp.sendEmail('',
""+ sub + "",
'',
{htmlBody: htmlforemail,
bcc: bccmail}
) } else if(mailTemp=="HTML4"){
const htmlTemplate = HtmlService.createTemplateFromFile("HTML4");
htmlTemplate.heading = heading;
htmlTemplate.subheading = subheading;
htmlTemplate.body = body;
htmlTemplate.footer = footer;
htmlTemplate.impfield1 = impfield1;
htmlTemplate.impfield2 = impfield2;
htmlTemplate.impfield3 = impfield3;
htmlTemplate.fieldvalue1 = fieldvalue1;
htmlTemplate.fieldvalue2 = fieldvalue2;
htmlTemplate.fieldvalue3 = fieldvalue3;
const htmlforemail = htmlTemplate.evaluate().getContent();
GmailApp.sendEmail('mayank.agarwal#aumcap.com',
""+ sub + "",
'',
{htmlBody: htmlforemail,
bcc: bccmail,
attachments: file1}
) }
}
I have this small setup where I have a Google Sheet, Google Appscript and Google form.
The user needs to input data in a Google Form - and once the sheet (linked with Form response) receives the updated row - a script is triggered which takes the data from the row and feeds it into the sheet and sends mail to the selected set of users.
Now the problem I am facing is that I need to send this mail to approx 100-150 people, however Googel appscript does not allow me to send mail to more than 30 participants at a time.
I understand that I need an Email service for this, however, I am unable to find any good solution wherein I can store my templates and the user just fills up data fields and shoots the mail.
Maybe because I am very new to this tech field so thats why.
Can anyone please guide me as to what is the setup I need to use for my purpose?
Thanks!
The first thing you need to do is to keep the BCC list as an array until it's necessary. This will allow us to make chunks out of it. This means removing the .toString() at the end of assigning bccmail.
Then, we need a custom function to send the email in batches of emails. I'm calling that function sendMassEmail.
function sendMassEmail(bccList, subject, plainBody, htmlBody, attachments) {
for (let bcc of chunks(bccList, 30)) {
GmailApp.sendEmail(
'',
subject,
plainBody,
{
htmlBody,
bcc: bcc.join(','),
attachments,
},
)
}
}
Chunks is a function that does exactly that, gets the elements of an array in chunks. My favorite implementation for this case is by using a generator.
I've kept the plain text body as it's important to generate it if you are sending it, as it is shown in most clients on the Inbox. Also, some of them can only read this ones (think smart watch).
The last argument (attachments) is optional.
Here is an example on how you would use it:
sendMassEmail(
bccmail,
sub.toString(),
'', // Should probably change it
htmlforemail,
file1,
)
Note that it's better to use toString() than concatenating into an empty string.
References
GmailApp.sendEmail(recipient, subject, body, options) (Apps Script reference)
for..of (MDN JavaScript reference)
Functions (MDN JavaScript guide)
Split array into chunks (StackOverflow question)
In Dynamic NAV 2018, I exposed page Sales Order (id 36) as web service, I'm following some guides to create Sales Order Header and Sales Order Lines, the Header can be created successfully, but the Sales Lines always get error "Standard Code Text does not exist..."
SOWS.Sales_Order_VS_Service testcreateSO = new SOWS.Sales_Order_VS_Service();
testcreateSO.UseDefaultCredentials = true;
SOWS.Sales_Order_VS SOEntity = new SOWS.Sales_Order_VS();
testcreateSO.Create(ref SOEntity);
SOEntity.Sell_to_Customer_No = "44094";
SOEntity.Store_No = "S9003";
SOEntity.Location_Code = "S9003";
testcreateSO.Update(ref SOEntity);
SOEntity.SalesLines = new SOWS.Sales_Order_Line[1];
SOEntity.SalesLines[0] = new SOWS.Sales_Order_Line();
testcreateSO.Update(ref SOEntity);
SOEntity.SalesLines[0].Type = SOWS.Type.Item;
SOEntity.SalesLines[0].TypeSpecified = true;
SOEntity.SalesLines[0].No = "208122";
SOEntity.SalesLines[0].Quantity = 1;
testcreateSO.Update(ref SOEntity);
System.Web.Services.Protocols.SoapException: 'The Standard Text does not exist. Identification fields and values: Code='208122''
Checking in table Sales Lines, a record of new order has been created but Type = 0 (means blank)
Document No_ Line No_ Sell-to Customer No_ Type No_ Location Code Document Type
SO210600017 10000 0 1
Please help
Solution
Instead of using only singe page Sales Order as web service, can expose page Sales Order Line as another web service, so full code as below:
SOWS.Sales_Order_VS_Service testcreateSO = new SOWS.Sales_Order_VS_Service();
testcreateSO.UseDefaultCredentials = true;
SOWS.Sales_Order_VS SOEntity = new SOWS.Sales_Order_VS();
testcreateSO.Create(ref SOEntity);
SOEntity.Sell_to_Customer_No = "44094";
SOEntity.Store_No = "S9003";
SOEntity.Location_Code = "S9003";
testcreateSO.Update(ref SOEntity);
//Using Sales Order Line page as web service from here
SOLinesWS.salesDocumentLines_Service saleslinesSV = new SOLinesWS.salesDocumentLines_Service
{
UseDefaultCredentials = true
};
SOLinesWS.salesDocumentLines saleslines = new SOLinesWS.salesDocumentLines();
saleslines.documentType = SOLinesWS.documentType.Order;
saleslines.documentTypeSpecified = true;
saleslines.documentNumber = SOEntity.No;
saleslines.type = SOLinesWS.type.Item;
saleslines.typeSpecified = true;
saleslines.number = "208122";
saleslines.quantity = 1;
saleslines.quantitySpecified = true;
saleslinesSV.Create(ref saleslines);
Can someone show me a code to update a enterprise resource custom field with lookup table ? Already ran the internet looking for some sample code but did not succeed.
You can create and update a custom field with a lookup table using the below code . But we can not update or delete builtin custom fields
var projContext = new ProjectContext(projectServerUrl);
CustomFieldCollection CustomField = projContext.CustomFields;
EntityTypes Entitytype = projContext.EntityTypes;
LookupTableCollection lookupTables = projContext.LookupTables;
projContext.Load(CustomField);
projContext.Load(Entitytype);
projContext.Load(lookupTables);
projContext.ExecuteQuery();
CustomFieldCreationInformation NewfieldInfo = new CustomFieldCreationInformation();
NewfieldInfo.Id = new Guid();
NewfieldInfo.Name = "The Name";
NewfieldInfo.Description = "The Description";
NewfieldInfo.IsWorkflowControlled = true;
NewfieldInfo.IsRequired = true;
NewfieldInfo.IsEditableInVisibility = false;
NewfieldInfo.IsMultilineText = false;
LookupTable lookuptable = lookupTables.ToList().Find(x => x.Name == "LookupTableName");
projContext.Load(lookuptable);
projContext.ExecuteQuery();
NewfieldInfo.LookupTable = lookuptable;
NewfieldInfo.EntityType = Entitytype.ProjectEntity;
NewfieldInfo.FieldType = CustomFieldType.TEXT;
projContext.CustomFields.Add(NewfieldInfo);
projContext.CustomFields.Update();
projContext.ExecuteQuery();
How do I create a tax rate in QBO using API v3 and the TaxService resource? When I try to add it the same way as I would any other object, Visual Studio gives me this error: "The type 'Intuit.Ipp.Data.TaxService' cannot be used as type parameter 'T' in the generic type or method Intuit.Ipp.DataService.DataService.Add(T)'. There is no implicit reference conversion from 'Intuit.Ipp.Data.TaxService' to 'Intuit.Ipp.Data.IEntity'."
Here's the code:
Intuit.Ipp.Data.TaxService ts = new Intuit.Ipp.Data.TaxService();
// Populate fields here...
DataService ds = new DataService(ServiceContext);
Intuit.Ipp.Data.TaxService newTs = ds.Add<Intuit.Ipp.Data.TaxService>(ts);
Use GlobalTaxService endpoint and JSON format only. Try this code:
GlobalTaxService taxSvc = new GlobalTaxService(context);
Intuit.Ipp.Data.TaxService taxCodetobeAdded = new Data.TaxService();
taxCodetobeAdded.TaxCode = "taxC_" + Guid.NewGuid().ToString("N");
QueryService<TaxAgency> taxagency = new QueryService<TaxAgency>(context);
TaxAgency taxagencyResult = taxagency.ExecuteIdsQuery("select * from TaxAgency").FirstOrDefault<TaxAgency>();
List<TaxRateDetails> lstTaxRate = new List<TaxRateDetails>();
TaxRateDetails taxdetail1 = new TaxRateDetails();
taxdetail1.TaxRateName = "taxR1_" + Guid.NewGuid().ToString("N");
taxdetail1.RateValue = 3m;
taxdetail1.RateValueSpecified = true;
taxdetail1.TaxAgencyId = taxagencyResult.Id.ToString();
taxdetail1.TaxApplicableOn = TaxRateApplicableOnEnum.Sales;
taxdetail1.TaxApplicableOnSpecified = true;
lstTaxRate.Add(taxdetail1);
TaxRateDetails taxdetail2 = new TaxRateDetails();
taxdetail2.TaxRateName = "taxR2_" + Guid.NewGuid().ToString("N");
taxdetail2.RateValue = 2m;
taxdetail2.RateValueSpecified = true;
taxdetail2.TaxAgencyId = taxagencyResult.Id.ToString();
taxdetail2.TaxApplicableOn = TaxRateApplicableOnEnum.Sales;
taxdetail2.TaxApplicableOnSpecified = true;
lstTaxRate.Add(taxdetail2);
//TaxRateDetails taxdetail3 = new TaxRateDetails();
//taxdetail3.TaxRateName = "rate298";
//taxdetail3.TaxRateId = "2";
//lstTaxRate.Add(taxdetail3);
taxCodetobeAdded.TaxRateDetails = lstTaxRate.ToArray();
Intuit.Ipp.Data.TaxService taxCodeAdded = taxSvc.AddTaxCode(taxCodetobeAdded);
I'm trying to query invoices using the .NET IPP DevKit v3.
Following all the directions found on the documentation site, I can query invoices and add skip/take/order by/where/etc to the query when using ONLY default fields. But, as soon as I add non-default fields, skip/take/order by/where/etc does NOT seem to work.
Here's the error:
System.ArgumentException was unhandled
HResult=-2147024809
Message=Expression of type 'System.Collections.Generic.IEnumerable`1[<>f__AnonymousType0`3[Intuit.Ipp.Data.Invoice,Intuit.Ipp.Data.Line[],Intuit.Ipp.Data.LinkedTxn[]]]' cannot be used for parameter of type 'System.Linq.IQueryable`1[<>f__AnonymousType0`3[Intuit.Ipp.Data.Invoice,Intuit.Ipp.Data.Line[],Intuit.Ipp.Data.LinkedTxn[]]]' of method 'System.Linq.IQueryable`1[<>f__AnonymousType0`3[Intuit.Ipp.Data.Invoice,Intuit.Ipp.Data.Line[],Intuit.Ipp.Data.LinkedTxn[]]] Skip[<>f__AnonymousType0`3](System.Linq.IQueryable`1[<>f__AnonymousType0`3[Intuit.Ipp.Data.Invoice,Intuit.Ipp.Data.Line[],Intuit.Ipp.Data.LinkedTxn[]]], Int32)'
Source=System.Core
What am I missing here?
Code:
string AppToken = "your AppToken goes here";
string AppConsumerKey = "your AppConsumerKey goes here";
string AppConsumerKeySecret = "your AppConsumerKeySecret goes here";
string AccessToken = "your AccessToken goes here";
string AccessTokenSecret = "your AccessTokenSecret goes here";
string RealmCompanyId = "your RealmId goes here";
OAuthRequestValidator oauthValidator = new OAuthRequestValidator(AccessToken, AccessTokenSecret, AppConsumerKey, AppConsumerKeySecret);
ServiceContext context = new ServiceContext(AppToken, RealmCompanyId, IntuitServicesType.QBD, oauthValidator);
QueryService<Intuit.Ipp.Data.Invoice> qs = new QueryService<Intuit.Ipp.Data.Invoice>(context);
// This works...
var defaultQuery = qs.Select(c => c).Skip(0).Take(10).OrderBy(c => c.Id);
var defaultList = defaultQuery.ToList();
// This works...
var nonDefaultQuery = qs.Select(c => new { c, c.Line, c.LinkedTxn });
var nonDefaultList = nonDefaultQuery.ToList();
// This does NOT work!!
var nonDefaultQueryWithSkip = qs.Select(c => new { c, c.Line, c.LinkedTxn }).Skip(0).Take(10);
var nonDefaultListWithSkip = nonDefaultQueryWithSkip.ToList();
I tried on the API explorer-
Select *,Line.*, LinkedTxn.* FROM Invoice startPosition 1 maxResults 10 (which is your last query) and it works fine but not from .net sdk. I will double check this on the .net SDK and get back to you. Can you verify that you get the correct results on API explorer from this query?
This now works in the latest version (IppDotNetSdkForQuickBooksApiV3.2.0.0)
Here's an example:
QueryService<Intuit.Ipp.Data.Invoice> qs = new QueryService<Intuit.Ipp.Data.Invoice>(context);
string query = string.Format("SELECT *, Line.* FROM Invoice ORDERBY Id STARTPOSITION {0} MAXRESULTS {1}", startPos, pageSize);
var recs = qs.ExecuteIdsQuery(query);
foreach (Intuit.Ipp.Data.Invoice rec in recs)
{
// do stuff...
}
.