I tried to show the shipping country in the Admin Sales Order Grid but nothing works.
I did check the customer address configuration twice and there I can see that the country variable exists and should be shown. But in the grid you can not see the shipping country.
Any workarounds?
I found a solution. Creating a Module and Rewrite Class.
app/code/Vendor/ExtendedAdminGrid/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="sales_order_grid_data_source" xsi:type="string">Vendor\ExtendedAdminGrid\Model\ResourceModel\Order\Grid\Collection</item>
</argument>
</arguments>
</type>
</config>
app/code/Vendor/ExtendedAdminGrid/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_ExtendedAdminGrid" setup_version="2.0.0">
<sequence>
<module name="Magento_Sales"/>
<module name="Magento_Backend"/>
</sequence>
</module>
</config>
app/code/Vendor/ExtendedAdminGrid/Model/ResourceModel/Order/Grid/Collection.php
<?php
namespace Vendor\ExtendedAdminGrid\Model\ResourceModel\Order\Grid;
class Collection extends \Magento\Sales\Model\ResourceModel\Order\Grid\Collection
{
protected function _renderFiltersBefore()
{
$this->getSelect()->joinLeft(
["soa" => "sales_order_address"],
"main_table.entity_id = soa.parent_id and soa.address_type = 'shipping'",
array('country_id')
)
->distinct();
parent::_renderFiltersBefore();
}
protected function _initSelect()
{
$this->addFilterToMap('created_at', 'main_table.created_at');
$this->addFilterToMap('base_grand_total', 'main_table.base_grand_total');
$this->addFilterToMap('grand_total', 'main_table.grand_total');
$this->addFilterToMap('store_id', 'main_table.store_id');
$this->addFilterToMap('store_name', 'main_table.store_name');
$this->addFilterToMap('order_id', 'main_table.order_id');
$this->addFilterToMap('order_increment_id', 'main_table.order_increment_id');
$this->addFilterToMap('billing_name', 'main_table.billing_name');
$this->addFilterToMap('billing_name', 'main_table.shipping_name');
$this->addFilterToMap('status', 'main_table.status');
parent::_initSelect();
}
}
app/code/Vendor/ExtendedAdminGrid/view/adminhtml/ui_component/sales_order_grid.xml
<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<columns name="sales_order_columns">
<column name="country_id">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Shipping Country ID</item>
</item>
</argument>
</column>
</columns>
</listing>
app/code/Vendor/ExtendedAdminGrid/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_ExtendedAdminGrid',
__DIR__
);
Thanks to Sergey for this great blogpost Modifying the default magento2 sales order grid — adding a coupon code column.
I'am try to convert XML on group of child nodes. Main information is in bill node, it must be group by bill numbers.
original XML, this is simplified version of original XML
<items>
<item>
<bill>10</bill>
<name>first (10)</name>
<price>111</price>
</item>
<item>
<bill>10</bill>
<name>second (10)</name>
<price>222</price>
</item>
<item>
<bill>10</bill>
<name>third (10)</name>
<price>333</price>
</item>
<item>
<bill>11</bill>
<name>first (11)</name>
<price>1</price>
</item>
<item>
<bill>11</bill>
<name>second (11)</name>
<price>2</price>
</item>
</items>
final file
<bills>
<bill>
<number>10</number>
<items>
<item>
<nameitem>first (10)</nameitem>
<priceitem>111</priceitem>
</item>
<item>
<nameitem>second (10)</nameitem>
<priceitem>222</priceitem>
</item>
<item>
<nameitem>third (10)</nameitem>
<priceitem>333</priceitem>
</item>
</items>
</bill>
<bill>
<number>11</number>
<items>
<item>
<nameitem>first (11)</nameitem>
<priceitem>1</priceitem>
</item>
<item>
<nameitem>second (11)</nameitem>
<priceitem>2</priceitem>
</item>
</items>
</bill>
</bills>
there is working XSLT, for basic grouping, but I have not idea, how to build another structure inside bill node, based on final XML
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="group-by-bill" match="item" use="bill"/>
<xsl:template match="items">
<bills>
<xsl:for-each select="item[generate-id()=generate-id (key('group-by-bill', bill)[1])]">
<bill number="{bill}">
<xsl:copy-of select="key('group-by-bill', bill)"/>
</bill>
</xsl:for-each>
</bills>
</xsl:template>
Use this:
<xsl:template match="items">
<bills>
<xsl:for-each select="item[generate-id()=generate-id (key('group-by-bill', bill)[1])]">
<bill>
<number><xsl:value-of select="bill"/></number>
<items>
<xsl:for-each select="//item[bill = current()/bill]">
<item>
<xsl:copy-of select="name|price"/>
</item>
</xsl:for-each>
</items>
</bill>
</xsl:for-each>
</bills>
</xsl:template>
See Transform at https://xsltfiddle.liberty-development.net/jyH9rM5
I am working on PowerShell. In that am trying to change the values of an existing config file values with the help of PowerShell and its working well.
But I faced a new task as below and strucked here in converting the values in PowerShell to override in my config file. For this task, I referred this link
If had a Code like this :
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="service.tasks" type="HRNetTaskService.TaskConfigurationSection, TaskService" />
</configSections>
<connectionStrings>
<add name="Production" connectionString="" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="RestServiceUrl" value="XXXXXXXXXXX" />
</appSettings>
<service.tasks>
<tasks>
<!-- App.config specified tasks are always recurring starting from whenever The Service first schedules it -->
<task name="ExpireRequirements" taskName="ExpireRequirements" recurrenceFactor="1" recurrenceType="Days" executeTime="01:00">
<parameters>
<param key="entityID">00000000-0000-0000-0000-000000000E01</param>
</parameters>
</task>
<task name="RequestExpiredRequirementsTask" taskName="RequestExpiredRequirementsTask" recurrenceFactor="1" recurrenceType="Days" executeTime="01:00">
<parameters>
<param key="entityID">00000000-0000-0000-0000-000000000E01</param>
<param key="CopyBatchSize">50</param>
</parameters>
</task>
<task name="UpdateRequirementChecksEffectiveDateTask" taskName="UpdateRequirementChecksEffectiveDateTask" recurrenceFactor="1" recurrenceType="Days" executeTime="01:00">
<parameters>
<param key="entityID">00000000-0000-0000-0000-000000000E01</param>
</parameters>
</task>
<task name="PeoplenetMatchAssignmentRefresh" taskName="PeoplenetMatchAssignmentRefresh">
<parameters>
<param key="checkInterval">300000</param>
<param key="batchCount">100</param>
</parameters>
</task>
</tasks>
</service.tasks>
<system.net>
<connectionManagement>
<add address="*" maxconnection="48" />
</connectionManagement>
</system.net>
<system.runtime.remoting>
<application name="server">
<channels>
<channel ref="tcp" port="8090">
<serverProviders>
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
How to change the values inside the service.tasks tag and system.runtime.remoting tags.
Refer to this code to update entityID value in ExpireRequirements task element (specify config file path in argument:-webCofig xxx):
param(
[string]$webConfig
)
$doc = (Get-Content $webConfig) -as [Xml]
$root=$doc.get_DocumentElement()
$ExpireRequirementsTask=$root."service.tasks"."tasks"."task" | where {$_.name -eq 'ExpireRequirements'}
Write-Output $ExpireRequirementsTask
$ExpireRequirementsTaskEntityID=$ExpireRequirementsTask."parameters"."param" | where {$_.key -eq 'entityID'}
Write-Output $ExpireRequirementsTaskEntityID
$ExpireRequirementsTaskEntityID.InnerText="11111111-0000-0000-0000-000000000E01"
$doc.Save($webConfig)
I get this error when I run my vxml app;
"ECMAScript runtime error: Compilation produced 1 syntax
errors.\n\nWhile evaluating:\n\"var acc_no = [37492414, 94190610,
23228367, 39574988, 64742440];\n\t\t\t\t\tfunction checkAccount(arr,
val) {\n\t\t\t\t\treturn arr.some(arrVal => val ===
arrVal);\n\t\t\t\t\t\t\t\t\t\t\t} \"";
Here's my vxml script where the error arises:
<?xml version="1.0" encoding="UTF-8"?>
<vxml xmlns:voxeo="http://community.voxeo.com/xmlns/vxml"
version="2.1" xml:lang="en-US"
xml:base="http://webhosting.voxeo.net/201985/www/">
<property name="inputmodes" value="dtmf"/>
<property name="termchar" value="#"/>
<property name="interdigittimeout" value="2s"/>
<property name="bargein" value="false"/>
<var name = "accountNumber"/>
<var name = "pinNumber"/>
<form id="userAuth" scope="document">
<var name="iMaxTries" expr="3"/>
<var name="iTriesAcc" expr="0"/>
<var name="iTriesPin" expr="0"/>
<var name="fatal" expr="'We are having technical difficulties validating your credentials. Try back later.'"/>
<catch event="event.pinNumber.invalid">
<!-- increment the attempt counter; if the count is exceeded, disconnect -->
<assign name="iTriesPin" expr="iTriesPin+1"/>
<if cond="iMaxTries == iTries">
<value expr="fatal"/>
<disconnect/>
<else/>
<!-- clear is unnecessary on a nomatch, but we use the same code to handle a bad filled -->
<clear namelist="pinNumber"/>
<reprompt/>
</if>
</catch>
<catch event="event.accountNumber.invalid">
<!-- increment the attempt counter; if the count is exceeded, disconnect -->
<assign name="iTriesAcc" expr="iTriesAcc+1"/>
<if cond="iMaxTries == iTries">
<value expr="fatal"/>
<disconnect/>
<else/>
<!-- clear is unnecessary on a nomatch, but we use the same code to handle a bad filled -->
<clear namelist="accountNumber"/>
<reprompt/>
</if>
</catch>
<!-- exec this on the first and second noinput/nomatch -->
<!-- each event has its own counter -->
<catch event="noinput">
I'm sorry. I didn't get you.
<reprompt />
</catch>
<!-- exec this on the third nomatch -->
<catch event="nomatch">
<throw event="event.password.invalid"/>
</catch>
<!-- silently disconnect on the third noinput -->
<catch event="noinput" count="3">
<disconnect/>
</catch>
<field name="accountNumber" type="digits?length=8">
<prompt> Please enter your account number followed by the pound key. </prompt>
<grammar mode="dtmf" version="1.0" root="pin"
tag-format="semantics/1.0">
<rule id="digit" scope="public" >
<one-of>
<item> 0 </item>
<item> 1 </item>
<item> 2 </item>
<item> 3 </item>
<item> 4 </item>
<item> 5 </item>
<item> 6 </item>
<item> 7 </item>
<item> 8 </item>
<item> 9 </item>
</one-of>
</rule>
<rule id="pin" scope="public">
<tag>out=""</tag>
<item repeat="8">
<ruleref uri="#digit"/>
<tag>out += rules.latest( );</tag>
</item>
</rule>
</grammar>
<filled>
<script> <![CDATA[
var acc_no = [37492414, 94190610, 23228367, 39574988, 64742440];
function checkAccount(arr, val) {
return arr.some(arrVal => val === arrVal);
}
]]> </script>
<block>
<var name="chk_acc" expr="checkAccount(acc_no, accountNumber);"/>
<if cond="chk_acc =='true'">
<goto next="#pinNumber"/>
<else/>
<prompt>Sorry, Account number not recognised. </prompt>
<throw event="event.accountNumber.invalid"/>
</if>
</block>
</filled>
</field>
<field name="pinNumber" type="digits?length=4">
<prompt> please enter your four digit pin followed by the pound key. </prompt>
<grammar mode="dtmf" version="1.0" root="pin"
tag-format="semantics/1.0">
<rule id="digit" scope="public" >
<one-of>
<item> 0 </item>
<item> 1 </item>
<item> 2 </item>
<item> 3 </item>
<item> 4 </item>
<item> 5 </item>
<item> 6 </item>
<item> 7 </item>
<item> 8 </item>
<item> 9 </item>
</one-of>
</rule>
<rule id="pin" scope="public">
<tag>out=""</tag>
<item repeat="4">
<ruleref uri="#digit"/>
<tag>out += rules.latest( );</tag>
</item>
</rule>
</grammar>
<filled>
<script> <![CDATA[
var pin_no = [2414, 0610,8367, 4988, 2440];
function checkPin(arr, val) {
return arr.some(arrVal => val === arrVal);
}
]]> </script>
<block>
<var name="chk_pin" expr="checkPin(pin_no, pinNumber);"/>
<if cond="chk_pin =='false'">
<prompt>Sorry, you have entered is an invalid pin. Please try again </prompt>
<throw event="event.pinNumber.invalid"/>
</if>
</block>
</filled>
</field>
<filled mode="all" namelist="accountNumber pinNumber">
<script> <![CDATA[
var accDetails = [
{acc_name: 'Lawrence Burkins', account: 37492414, pin: 2414, acc_type: 'checking', acc_bal: 2372351.74 , acc_br:'Montreal'},
{acc_name: 'Ola Macaulay', account: 94190610, pin: 0610, acc_type: 'checking', acc_bal: 908242.49 , acc_br:'Tisdale'},
{acc_name: 'Judy Cefalu', account: 23228367, pin: 8367, acc_type: 'checking', acc_bal: 15700526.57 , acc_br:'Toronto'},
{acc_name: 'Mellisa Garcia', account: 39574988, pin: 4988, acc_type: 'checking', acc_bal: 568201.26 , acc_br:'Prince Albert'},
{acc_name: '', account: 64742440, pin: 2440, acc_type: 'checking', acc_bal: 1952000.00 , acc_br:'Fort McMurray'},
];
function accDetails(details) {
return details.account === accountNumber ;
}
var newDetail = accDetails.find(accDetails);
var myDetail = [newDetail];
var myBal = myDetail.slice(0, 4);
]]> </script>
<var name = "accountBalance" expr = "myBal.toString()"/>
<prompt>
Your Checking account balance is <prosody rate="slow"><say-as type="currency"> $ + <value class="currency" expr="accountBalance"/> </say-as></prosody>
</prompt>
<goto next="after_bal.vxml"/>
</filled>
</form>
</vxml>
I am still new to vxml and ecmascript.
The ECMAScript in question seems to be syntactically correct:
var acc_no = [37492414, 94190610, 23228367, 39574988, 64742440];
function checkAccount(arr, val) {
return arr.some(arrVal => val === arrVal);
}
I would suggest breaking this piecemeal and reduce the complexity of the VXML code to debug it. Use a very basic VXML file with one simple field, put the above ECMAScript in the filled section and then see if you get the same error. If you do, move the script further up in the code (i.e not in the filled section) and again check if you get the same error.
The error statement is a bit confusing because of the linefeeds etc. Does the error message look like that when you see it the first time?
I am reading the following file in powershell.
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<nested1>
<level1 xsi:nil="true" />
<level2>2</level2>
</nested1>
<nested2>
<level1 xsi:nil="true" />
<level2>2</level2>
</nested2>
</root>
using...
[xml]$XmlDoc = get-content $XMLFile
I would like to set
$XmlDoc.root.nested1.level2
so it has the attribute xsi:nil="true"
so the file appears as
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<nested1>
<level1 xsi:nil="true" />
<level2 xsi:nil="true" />
</nested1>
<nested2>
<level1 xsi:nil="true" />
<level2>2</level2>
</nested2>
</root>
Many Thanks for any advice offered.
Use SetAttribute() and provide the namespace URI.
$node = $XmlDoc.SelectSingleNode('//nested1/level2')
$node.SetAttribute('nil', 'http://www.w3.org/2001/XMLSchema-instance', 'true') |
Out-Null