Drupal removing a node reference from a node - drupal-6

Ok, trying to process a script, both PHP and JavaScript, where I am moving a particular content type NODE from one reference to another. This is the structure:
I have a PROJECT
Inside each PROJECT are PAGES
Inside each PAGE are CALLOUTS
and Inside each CALLOUT are PRODUCTS.
What I want to do is take a PRODUCT from one CALLOUT to another CALLOUT. I am able to merge these, but now what I want to do is delete the first instance. An example:
I have PRODUCT AAG-794200 that is on PAGE 6 CALLOUT A. I am merging that PRODUCT with PAGE 6 CALLOUT B.
I can get the product to merge, but now I need to remove it from CALLOUT A. Here is my code:
$merge = explode(',', $merge); //Merge SKUs
$mpages = explode(',', $mpages); //Merge Pages
$mcallouts = explode(',', $mcallouts); //Merge Callouts
$mcallout_nid = explode(',', $mcallout_nid); //Merge Current callout
$length = count($merge);
$e = 0;
while ($e < $length) {
//Where is the SKU going to?
$to_callout_letter = strtoupper($mcallouts[$e]);
$to_page_num = $mpages[$e];
$sku = $merge[$e];
$from_callout = $mcallout_nid[$e];
//Where is the SKU coming from?
$other_callout = node_load($from_callout);
//Need page ID of current callout for project purposes
$page_nid = $other_callout->field_page[0]['nid'];
$page = node_load($page_nid);
//Need the project NID
$project_nid = $page->field_project[0]['nid'];
//We need to get the NID of the page we are going to
$page_nid = db_query('SELECT * FROM content_type_page WHERE field_page_order_value = "%d" and field_project_nid = "%d" ORDER BY vid DESC LIMIT 1', $to_page_num, $project_nid);
$page_nid_res = db_fetch_array($page_nid);
$to_page_nid = $page_nid_res['nid'];
//We need to get the NID of the callout here
$co_nid = db_query('SELECT * FROM content_type_callout WHERE field_identifier_value = "%s" and field_page_nid = "%d"', $to_callout_letter, $to_page_nid);
$co_nid_res = db_fetch_array($co_nid);
$to_callout_letter_nid = $co_nid_res['nid'];
//Load the present callout the SKU resides on
$f_callout = node_load($from_callout);
$callout = node_load($to_callout_letter_nid);
$long = count($f_callout->field_skus);
$deletecallout = array();
foreach($f_callout->field_skus as $skus) {
$s = 0;
while ($s < $long) {
if($skus['nid'] == $sku) {
$callout->field_skus[] = $skus;
$s++;
}
else {
$deletecallout[] = $skus;
$s++;
}
}
}
foreach($other_callout->field_images as $old_image) {
$callout->field_images[] = $old_image;
}
foreach($other_callout->field_line_art as $old_image) {
$callout->field_line_art[] = $old_image;
}
foreach($other_callout->field_swatches as $old_image) {
$callout->field_swatches[] = $old_image;
}
$callout->field_copy_text[0]['value'] .= $other_callout->field_copy_text[0]['value'];
$callout->field_notes[0]['value'] .= $other_callout->field_notes[0]['value'];
$callout->field_image_notes[0]['value'] .= $other_callout->field_image_notes[0]['value'];
$callout->field_status[0]['value'] = 'In Process';
node_save($callout);
This causes the PRODUCTS to MERGE, but not delete the original.
Thanks for any help. I know it's something simple, and it will be a palm-to-face moment.

I was actually able to solve this myself. #Chris - The brace ended after node_save(callout); I must have missed that when I copied and pasted. However, here is the code I ended up using:
$merge = explode(',', $merge); //Merge SKUs
$mpages = explode(',', $mpages); //Merge Pages
$mcallouts = explode(',', $mcallouts); //Merge Callouts
$mcallout_nid = explode(',', $mcallout_nid); //Merge Current callout
if($merge[0] !== '0') {
//Store NIDs of Old Callouts to the proper SKU
$oc_sku = array();
$oc_sku_e = count($merge);
$oc_sku_ee = 0;
while ($oc_sku_ee < $oc_sku_e) {
$curr_sku = $merge[$oc_sku_ee];
$curr_oldco = $mcallout_nid[$oc_sku_ee];
$oc_sku[$curr_sku] = $curr_oldco;
$oc_sku_ee++;
}
//Convert page numbers to page_nids
$pc = count($mpages); //How many pages are we getting
$pc_e = 0;
while($pc_e < $pc) {
$nid = $mpages[$pc_e];
$sql = db_query('SELECT * FROM content_type_page WHERE field_page_order_value = "%d" AND field_project_nid = "%d" ORDER BY vid DESC LIMIT 1', $nid, $project_nid);
$res = db_fetch_array($sql);
if($res) {
$npage_arr[] = $res['nid'];
} else { //If there is no page, we need to create it here.
$node = new StdClass();
$node->type = 'page';
$node->title = 'Page ' . $nid . ' of ' . $project->title;
$node->field_project[0]['nid'] = $project_nid;
$node->field_page_order[0]['value'] = $nid;
$node = node_submit($node);
node_save($node);
$npage_arr[] = $node->nid;
}
$pc_e++;
}
// Convert callout letters to callout_nids
$coc = count($mcallouts);
$coc_e = 0;
while($coc_e < $coc) {
$cnid = strtoupper($mcallouts[$coc_e]);
$pnid = $npage_arr[$coc_e];
$page_node = node_load($pnid);
$sql = db_query('SELECT * FROM content_type_callout WHERE field_identifier_value = "%s" AND field_page_nid = "%d" ORDER BY vid DESC LIMIT 1', $cnid, $pnid);
$res = db_fetch_array($sql);
if($res) {
$cpage_arr[] = $res['nid'];
} else { //If there is no callout that exists, we need to make it here.
$callout_node = new stdClass();
$callout_node->type = 'callout';
$callout_node->field_page[0]['nid'] = $pnid;
$callout_node->field_identifier[0]['value'] = $cnid;
$callout_node->field_sequence[0]['value'] = 0;
$callout_node->title = "Callout ".$callout." on page ".$page_node->field_page_order[0]['value'];
$callout_node->field_project[0]['nid'] = $project->nid;
$callout_node->field_wholesaler[0]['value'] = $project->field_wholesaler[0]['value'];
$callout_node->field_skus = array();
$callout_node->status = 1;
$callout_node->uid = 1;
$callout_node->revision = true;
$callout_node = node_submit($callout_node);
node_save($callout_node);
$cpage_arr[] = $callout_node->nid;
}
$coc_e++;
}
//Now we need to assign the skus to the appropriate callout for processing
$coc2 = count($cpage_arr);
$coc_e2 = 0;
while($coc_e2 < $coc2) {
$co = $cpage_arr[$coc_e2];
if($co !== '0') {
$sku = $merge[$coc_e2];
$m_arr[$co][] = $sku;
}
$coc_e2++;
}
//we need a way to centrally store all NID's of SKUs to the callouts they belong to
$oc_arr = array();
$oc = count($mcallout_nid);
$oc_e = 0;
while($oc_e < $oc) {
$f_callout = $mcallout_nid[$oc_e];
$former_callout = node_load($f_callout);
foreach($former_callout->field_skus as $key=>$skus) {
$oc_arr[] = $skus;
}
$oc_e++;
}
//Now we are processing the Pages/Callouts/SKUs to save
$pc_e2 = 0;
foreach($m_arr as $key=>$values) {
$callout = node_load($key);
foreach($values as $value) {
$oc = count($oc_arr);
$oc_e = 0;
while($oc_e < $oc) {
$skus = $oc_arr[$oc_e];
if($value == $skus['nid']) {
$callout->field_skus[] = $skus;
//$nid = $oc_sku[$value];
$old_callout_info[] = $oc_sku[$value];
$oc_e = $oc;
}
else {
$oc_e++;
}
}
}
foreach($old_callout_info as $nid) {
/* $nid = $oc_sku[$value]; */
$former_callout = node_load($nid);
foreach($former_callout->field_images as $old_image) {
$callout->field_images[] = $old_image;
}
foreach($former_callout->field_line_art as $old_image) {
$callout->field_line_art[] = $old_image;
}
foreach($former_callout->field_swatches as $old_image) {
$callout->field_swatches[] = $old_image;
}
$callout->field_copy_text[0]['value'] .= $former_callout->field_copy_text[0]['value'];
}
$callout->field_notes[0]['value'] .= $former_callout->field_notes[0]['value'];
$callout->field_image_notes[0]['value'] .= $former_callout->field_image_notes[0]['value'];
$callout->field_logos = $former_callout->field_logos;
$callout->field_affiliations = $former_callout->field_affiliations;
$callout->field_graphics = $former_callout->field_graphics;
$callout->revision = 1;
$callout->field_status[0]['value'] = 'inprocess';
node_save($callout);
$pc_e2++;
}
}
I realize this can probably be simplified in a way, but as for now, this works perfectly considering what I'm trying to do. No complaints from the client so far. Thanks for taking a look Drupal Community.

Related

Laravel Export to excel file not working for only five thousand data

I've been trying to create an export to excel file api in a production project.
But this api is working only for fewer data.
But when exporting for five thousand data, the excel file is downloaded after a long time with broken data in excel file.
Here is the code:
The route file-
Route::group(['prefix' => 'v1/export'], function () {
Route::get('/applied-candidate/{job_id}', 'Job\JobPostingUserController#exportAppliedCandidate');
});
In controller-
public function exportAppliedCandidate($jobposting_id)
{
$fileName = 'candidate_list_' . Carbon::now()->toDateString();
$exportable = new ExportableFromCollection(JobPostingUser::exportCandiateList($jobposting_id), JobPostingUser::listHeader());
return Excel::download($exportable, $fileName . '.xlsx');
}
In model-
public static function exportCandiateList($job_id): array {
$candidateList = JobPostingUser::where('posting_id', $job_id)
->join('users', 'users.id', '=' ,'job_posting_user.user_id')
->join('profile_basics', 'profile_basics.user_id', '=' ,'job_posting_user.user_id')
->join('job_postings', 'job_postings.id', '=' , 'job_posting_user.posting_id')
->select('job_postings.title as job_name',
'users.id as candidate_id',
'users.first_name',
'users.last_name',
'profile_basics.date_of_birth',
'profile_basics.gender',
'profile_basics.phone_personal',
'users.email',
'profile_basics.total_experience')->get()->toArray();
$final_result = [];
foreach($candidateList as $candidate) {
$bachelor = ProfileEducation::getBachelorInfo($candidate['candidate_id']);
$msc = ProfileEducation::getMasterInfo($candidate['candidate_id']);
$candidateInfo = [];
$job_name = JobPosting::where('id', $job_id)->first();
$job_name = $job_name ? $job_name->title: $job_id;
$candidateInfo['job'] = $job_name;
$candidateInfo['candidate_id'] = $candidate['candidate_id'];
$candidateInfo['name'] = $candidate['first_name'].' '.$candidate['last_name'];
$candidateInfo['date_of_birth'] = date('Y-m-d', strtotime($candidate['date_of_birth']));
$candidateInfo['gender'] = $candidate['gender'];
$candidateInfo['phone_personal'] = $candidate['phone_personal'];
$candidateInfo['email'] = $candidate['email'];
if($bachelor) {
$candidateInfo['b_university'] = empty($bachelor['institution']) ? $bachelor['other_institution'] : $bachelor['institution']['name'];
$candidateInfo['b_field'] = $bachelor['field'] ? ProfileService::getBachelorDegreeName($bachelor['field']): 'N/A';
$candidateInfo['b_major'] = $bachelor['major'] ? $bachelor['major']: 'N/A';
$candidateInfo['b_grade'] = $bachelor['grade'] ? $bachelor['grade']: 'N/A';
} else {
$candidateInfo['b_university'] = 'N/A';
$candidateInfo['b_field'] = '';
$candidateInfo['b_major'] = '';
$candidateInfo['b_grade'] = '';
}
if($msc) {
$candidateInfo['m_university'] = empty($msc['institution']) ? $msc['other_institution'] : $msc['institution']['name'];
$candidateInfo['m_field'] = $msc['field'] ? ProfileService::getMastersDegreeName($msc['field']): 'N/A';
$candidateInfo['m_major'] = $msc['major'] ? $msc['major']: 'N/A';
$candidateInfo['m_grade'] = $msc['grade'] ? $msc['grade']: 'N/A';
} else {
$candidateInfo['m_university'] = 'N/A';
$candidateInfo['m_field'] = '';
$candidateInfo['m_major'] = '';
$candidateInfo['m_grade'] = '';
}
$expericnece = self::getExperience($candidate['candidate_id']);
if($expericnece) {
$candidateInfo['company_name'] = $expericnece['company_name'];
$candidateInfo['started_in'] = $expericnece['started_in'];
$candidateInfo['ended_in'] = $expericnece['ended_in'];
$candidateInfo['responsibilitie'] = $expericnece['job_responsibilities'];
} else {
$candidateInfo['company_name'] = '';
$candidateInfo['started_in'] = '';
$candidateInfo['ended_in'] = '';
$candidateInfo['responsibilitie'] = '';
}
$candidateInfo['total_experience'] = $candidate['total_experience'];
$final_result[] = $candidateInfo;
}
return $final_result;
}
After exporting just few numbers are showing some columns in excel file. But file is correctly exported for lesser data(500 items).
Please suggest how I can change/optimise this query to work for any number of data?

Hide a product in Kentico 10

I am performing CRUD operations for products of e-commerce site in kentico 10.I can add and update products using below API
SKUInfoProvider.SetSKUInfo(updateProduct);
Also there is an API for deleting product
SKUInfoProvider.DeleteSKUInfo(updateProduct);
But I do not wish to delete the product from database,rather just disable them so that they do not show up to the end users and still stay in the database .
I tried to set SKUEnabled as false but still user can see the product.So, I used below code to hide the products
ProductNode.SetValue("DocumentPublishTo", DateTime.Now.AddDays(-1));
But my code setup adds a new product with above disabled property.Here is my code
foreach (DataRow dr in dt.Rows)
{
manufacturer = GetManufacturer(Convert.ToString(dr["MANUFACTURER_NAME"]));
department = GetDepartment(Convert.ToString(dr["CATEGORY_OF_PRODUCT_1"]));
var sku = new SKUInfo
{
SKUNumber = Convert.ToString(dr["MANUFACTURER_PART_NUMBER"]),
SKUName = Convert.ToString(dr["MANUFACTURER_PART_NUMBER"]),
SKUDescription = Convert.ToString(dr["TECHNICAL_SPECIFICATIONS"]).Trim('"'),
SKUShortDescription = Convert.ToString(dr["SHORT_DESCRIPTION"]).Trim('"'),
SKUPrice = ValidationHelper.GetDouble(dr["RESELLER_BUY_INC"], 0),
SKURetailPrice = ValidationHelper.GetDouble(dr["RRP_INC"], 0),
SKUEnabled = false,
SKUSiteID = siteId,
SKUProductType = SKUProductTypeEnum.Product,
SKUManufacturerID = manufacturer.ManufacturerID,
SKUDepartmentID = department.DepartmentID,
SKUHeight = ValidationHelper.GetDouble(dr["HEIGHT"], 0),
SKUWidth = ValidationHelper.GetDouble(dr["WIDTH"], 0),
SKUWeight = ValidationHelper.GetDouble(dr["WEIGHT"], 0),
SKUDepth = ValidationHelper.GetDouble(dr["LENGTH"], 0),
SKUAvailableItems = 1,
SKUSellOnlyAvailable = true
};
try
{
SKUInfo updateProduct = SKUInfoProvider.GetSKUs()
.WhereEquals("SKUNumber", sku.SKUNumber)
.FirstObject;
sku.SKUPrice += sku.SKUPrice * 0.015;
if (updateProduct != null)
{
updateProduct.SKUNumber = sku.SKUNumber; updateProduct.SKUName = sku.SKUName;
SKUInfoProvider.SetSKUInfo(updateProduct);
}
else
{
SKUInfoProvider.SetSKUInfo(sku);
}
if (!sku.SKUEnabled)
{
SKUTreeNode productDoc = (SKUTreeNode)SKUTreeNode.New(productDocumentType.ClassName, tree);
if (sku.SKUEnabled == false)
{
productDoc.DocumentPublishTo = DateTime.Now.AddDays(-1);
}
productDoc.DocumentSKUName = Convert.ToString(dr["MANUFACTURER_PART_NUMBER"]);
productDoc.DocumentSKUDescription = sku.SKUDescription;
productDoc.NodeSKUID = sku.SKUID;
productDoc.DocumentCulture = cultureCode;
productDoc.DocumentName = Convert.ToString(dr["MANUFACTURER_PART_NUMBER"]);
}
}
catch (Exception ex)
{
error += "error";
}
}
Please provide the possible solution.There ain't no property such as DocumentPublishTo in SKUInfo,hence I used it with SKUTreeNode which you can find in code setup.
SKUTreeNode productDoc = (SKUTreeNode)SKUTreeNode.New(productDocumentType.ClassName, tree);
if (sku.SKUEnabled == false)
{
productDoc.DocumentPublishTo = DateTime.Now.AddDays(-1);
}
You need to get the node for the SKU, not create a new one. from the documentation :
SKUTreeNode productDoc = (SKUTreeNode)tree.SelectNodes()
.Path("/Products/NewProduct")
.OnCurrentSite()
.CombineWithDefaultCulture()
.FirstObject;
productDoc.DocumentPublishTo = DateTime.Now.AddDays(-1)

Batch bills- Submission Id

I need to grab the batch bill submission id (from different vendors) of the object from netsuite.Does anyone know how to do this?
TransactionSearchBasic transSearch = new TransactionSearchBasic();
SearchResult resVendorBill = service.search(transSearch);
resVendorBill.pageSize = 25;
resVendorBill.pageSizeSpecified = true;
resVendorBill.totalRecords = SearchRecentTransCount;
resVendorBill.totalRecordsSpecified = true;
transSearch.recordType = new SearchStringField() { #operator = SearchStringFieldOperator.#is, searchValue = "vendorpayment", operatorSpecified = true };
SearchResult resVendorPayment = service.search(transSearch);
if (resVendorPayment.status.isSuccess)
{
Record[] searchPaymentRecords = resVendorPayment.recordList;
if (searchPaymentRecords != null && searchPaymentRecords.Length >= 1)
{
List<VendorPayment> lstVendorPayments = searchPaymentRecords.Select(ep => (VendorPayment)ep).OrderByDescending(epo => epo.createdDate).Take(SearchRecentTransCount).ToList();
}
}

NetSuite SuiteTalk API - Get Inventory Details

I'm using the SuiteTalk (API) service for NetSuite to retrieve a list of Assemblies. I need to load the InventoryDetails fields on the results to view the serial/lot numbers assigned to the items. This is the current code that I'm using, but the results still show those fields to come back as NULL, although I can see the other fields for the AssemblyBuild object. How do I get the inventory details (serials/lot#'s) to return on a transaction search?
public static List<AssemblyBuildResult> Get()
{
var listAssemblyBuilds = new List<AssemblyBuildResult>();
var service = Service.Context();
var ts = new TransactionSearch();
var tsb = new TransactionSearchBasic();
var sfType = new SearchEnumMultiSelectField
{
#operator = SearchEnumMultiSelectFieldOperator.anyOf,
operatorSpecified = true,
searchValue = new string[] { "_assemblyBuild" }
};
tsb.type = sfType;
ts.basic = tsb;
ts.inventoryDetailJoin = new InventoryDetailSearchBasic();
// perform the search
var response = service.search(ts);
response.pageSizeSpecified = true;
// Process response
if (response.status.isSuccess)
{
// Process the records returned in the response
// Get more records with pagination
if (response.totalRecords > 0)
{
for (var x = 1; x <= response.totalPages; x++)
{
var records = response.recordList;
foreach (var t in records)
{
var ab = (AssemblyBuild) t;
listAssemblyBuilds.Add(GetAssemblyBuildsResult(ab));
}
if (response.pageIndex < response.totalPages)
{
response = service.searchMoreWithId(response.searchId, x + 1);
}
}
}
}
// Parse and return NetSuite WorkOrder into assembly WorkOrderResult list
return listAssemblyBuilds;
}
After much pain and suffering, I was able to solve this problem with the following code:
/// <summary>
/// Returns List of AssemblyBuilds from NetSuite
/// </summary>
/// <returns></returns>
public static List<AssemblyBuildResult> Get(string id = "", bool getDetails = false)
{
// Object to populate and return results
var listAssemblyBuilds = new List<AssemblyBuildResult>();
// Initiate Service and SavedSearch (TransactionSearchAdvanced)
var service = Service.Context();
var tsa = new TransactionSearchAdvanced
{
savedSearchScriptId = "customsearch_web_assemblysearchmainlist"
};
// Filter by ID if specified
if (id != "")
{
tsa.criteria = new TransactionSearch()
{
basic = new TransactionSearchBasic()
{
internalId = new SearchMultiSelectField
{
#operator = SearchMultiSelectFieldOperator.anyOf,
operatorSpecified = true,
searchValue = new[] {
new RecordRef() {
type = RecordType.assemblyBuild,
typeSpecified = true,
internalId = id
}
}
}
}
};
}
// Construct custom columns to return
var tsr = new TransactionSearchRow();
var tsrb = new TransactionSearchRowBasic();
var orderIdCols = new SearchColumnSelectField[1];
var orderIdCol = new SearchColumnSelectField();
orderIdCols[0] = orderIdCol;
tsrb.internalId = orderIdCols;
var tranDateCols = new SearchColumnDateField[1];
var tranDateCol = new SearchColumnDateField();
tranDateCols[0] = tranDateCol;
tsrb.tranDate = tranDateCols;
var serialNumberCols = new SearchColumnStringField[1];
var serialNumberCol = new SearchColumnStringField();
serialNumberCols[0] = serialNumberCol;
tsrb.serialNumbers = serialNumberCols;
// Perform the Search
tsr.basic = tsrb;
tsa.columns = tsr;
var response = service.search(tsa);
// Process response
if (response.status.isSuccess)
{
var searchRows = response.searchRowList;
if (searchRows != null && searchRows.Length >= 1)
{
foreach (SearchRow t in searchRows)
{
var transactionRow = (TransactionSearchRow)t;
listAssemblyBuilds.Add(GetAssemblyBuildsResult(transactionRow, getDetails));
}
}
}
// Parse and return NetSuite WorkOrder into assembly WorkOrderResult list
return listAssemblyBuilds;
}
private static string GetAssemblyBuildLotNumbers(string id)
{
var service = Service.Context();
var serialNumbers = "";
var tsa = new TransactionSearchAdvanced
{
savedSearchScriptId = "customsearch_web_assemblysearchlineitems"
};
service.searchPreferences = new SearchPreferences { bodyFieldsOnly = false };
tsa.criteria = new TransactionSearch()
{
basic = new TransactionSearchBasic()
{
internalId = new SearchMultiSelectField
{
#operator = SearchMultiSelectFieldOperator.anyOf,
operatorSpecified = true,
searchValue = new[] {
new RecordRef() {
type = RecordType.assemblyBuild,
typeSpecified = true,
internalId = id
}
}
}
}
};
// Construct custom columns to return
var tsr = new TransactionSearchRow();
var tsrb = new TransactionSearchRowBasic();
var orderIdCols = new SearchColumnSelectField[1];
var orderIdCol = new SearchColumnSelectField();
orderIdCols[0] = orderIdCol;
tsrb.internalId = orderIdCols;
var serialNumberCols = new SearchColumnStringField[1];
var serialNumberCol = new SearchColumnStringField();
serialNumberCols[0] = serialNumberCol;
tsrb.serialNumbers = serialNumberCols;
tsr.basic = tsrb;
tsa.columns = tsr;
var response = service.search(tsa);
if (response.status.isSuccess)
{
var searchRows = response.searchRowList;
if (searchRows != null && searchRows.Length >= 1)
{
foreach (SearchRow t in searchRows)
{
var transactionRow = (TransactionSearchRow)t;
if (transactionRow.basic.serialNumbers != null)
{
return transactionRow.basic.serialNumbers[0].searchValue;
}
}
}
}
return serialNumbers;
}
private static AssemblyBuildResult GetAssemblyBuildsResult(TransactionSearchRow tsr, bool getDetails)
{
if (tsr != null)
{
var assemblyInfo = new AssemblyBuildResult
{
NetSuiteId = tsr.basic.internalId[0].searchValue.internalId,
ManufacturedDate = tsr.basic.tranDate[0].searchValue,
SerialNumbers = tsr.basic.serialNumbers[0].searchValue
};
// If selected, this will do additional NetSuite queries to get detailed data (slower)
if (getDetails)
{
// Look up Lot Number
assemblyInfo.LotNumber = GetAssemblyBuildLotNumbers(tsr.basic.internalId[0].searchValue.internalId);
}
return assemblyInfo;
}
return null;
}
What I learned about pulling data from NetSuite:
Using SavedSearches is the best method to pull data that doesn't automatically come through in the API objects
It is barely supported
Don't specify an ID on the SavedSearch, specify a criteria in the TransactionSearch to get one record
You will need to specify which columns to actually pull down. NetSuite doesn't just send you the data from a SavedSearch automatically
You cannot view data in a SavedSearch that contains a Grouping
In the Saved Search, use the Criteria Main Line = true/false to read data from the main record (top of UI screen), and line items (bottom of screen)

How to make parent child relationship in C1flexgrid

I am using C1Flexgrid and I need to make parent child relation in this grid. But child details need to show in same grid (no other grid ) and when I clicked on + expand should happen and vice versa.
I have written below code where I am having one column in datatable related to parent and child . If it is parent then I am making it 1 else 0.
When I tried with this code. R2 row is coming as child node of r which should not be a case as it is parent node.
Please help me on this .
private void Form3_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable("customers");
dt.Columns.Add("abc");
dt.Columns.Add("ddd");
dt.Columns.Add("eee");
dt.Columns.Add("parent");
var r = dt.NewRow();
r["abc"] = "11";
r["ddd"] = "12";
r["eee"] = "13";
r["parent"] = "1";
var r1 = dt.NewRow();
r1["ddd"] = "12";
r1["eee"] = "14";
r1["parent"] = "0";
var r2 = dt.NewRow();
r2["abc"] = "11";
r2["ddd"] = "1222";
r2["eee"] = "14";
r2["parent"] = "1";
var rr32 = dt.NewRow();
rr32["abc"] = "11";
rr32["ddd"] = "1222";
rr32["eee"] = "14";
rr32["parent"] = "0";
dt.Rows.Add(r);
dt.Rows.Add(r1);
dt.Rows.Add(r2);
dt.Rows.Add(rr32);
grid1.DataSource = dt;
GroupBy("parent", 1);
// show outline tree
grid1.Tree.Column = 2;
// autosize to accommodate tree
grid1.AutoSizeCol(grid1.Tree.Column);
grid1.Tree.Show(1);
}
void GroupBy(string columnName, int level)
{
object current = null;
for (int r = grid1.Rows.Fixed; r < grid1.Rows.Count; r++)
{
if (!grid1.Rows[r].IsNode)
{
var value = grid1[r, columnName];
string value2 = grid1[r, "parent"].ToString();
if (!object.Equals(value, current))
{
// value changed: insert node, apply style
if (value2.Equals("0"))
{
grid1.Rows.InsertNode(r, level);
grid1.Rows[r].Style = _nodeStyle[Math.Min(level, _nodeStyle.Length - 1)];
r++;
}
// show group name in first scrollable column
//grid1[r, grid1.Cols.Fixed+1] = value;
// update current value
current = value;
}
}
}
}
}
Your code was almost there, i have manipulated GroupBy method to fit your need. It solves your current requirement but you have to handle sorting and other functionalists of grid yourself.
Hope this helps!
void GroupBy(string columnName, int level)
{
object current = null;
for (int r = grid1.Rows.Fixed; r < grid1.Rows.Count; r++)
{
if (!grid1.Rows[r].IsNode)
{
var value = grid1[r, columnName];
if (!object.Equals(value, current))
{
// value changed: insert node, apply style
grid1.Rows.InsertNode(r, level);
grid1.Rows[r].Style = _nodeStyle[Math.Min(level, _nodeStyle.Length - 1)];
// show group name in first scrollable column
Row row = grid1.Rows[r + 1];
for (int i = 0; i < grid1.Cols.Count; i++)
{
grid1[r, i] = row[i];
}
grid1.Rows[r + 1].Visible = false;
r++;
// update current value
current = value;
}
}
}
}

Resources