Delete/update Configurable Product with SOAP Api v2 Magento - api

I am trying to delete a configurable product in my cart wiht shoppingCartProductRemove with Api SOAP v2, but the api return
Please specify the product's option (s)
this is my Soap requets:
<?xml version="1.0" encoding="UTF-8"?>
<v:Envelope xmlns:v="http://schemas.xmlsoap.org/soap/envelope/" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<v:Header />
<v:Body>
<shoppingCartProductRemove xmlns="http://dev.WEBPAGE.mx/index.php/api/v2_soap" id="o0" c:root="1">
<sessionId>e6ad1063fd8f8a5b1637ec7b2bedb0ed</sessionId>
<quoteId>1016</quoteId>
<products>
<shoppingcartproductentity>
<product_id>5730</product_id>
<sku i:null="true" />
<qty>0.0</qty>
<qtySpecified>false</qtySpecified>
<options i:type="d:anyType">
<associativeentity>
<key>92</key>
<value>410</value>
</associativeentity>
<associativeentity>
<key>138</key>
<value>406</value>
</associativeentity>
</options>
<bundle_option i:type="d:anyType">
<associativeentity>
<key>92</key>
<value>410</value>
</associativeentity>
<associativeentity>
<key>138</key>
<value>406</value>
</associativeentity>
</bundle_option>
<bundle_option_qty i:null="true" />
<links i:null="true" />
</shoppingcartproductentity>
</products>
<storeId>1</storeId>
</shoppingCartProductRemove>
</v:Body>
</v:Envelope>
The configurable product is 5730 ... this have associated a simple product (id: 5735) with the attributes:
attributeID = 92 value = color (Attribute)
valueID = 410 value = black (Attribute Options)
attributeId = 138 value = Size (Attribute)
valueId = 406 value = tall (Attribute Options)
What is wrong? . How do I can remove a configurable product?

Related

I am having trouble to add tags with nsmap for lxml library

I have wrote a function to generate Google Merchant RSS Feed with lxml library
I have the following code which is shortened for single tag:
from lxml import etree
def generate_xml(self):
nsmap = {
"g": "http://base.google.com/ns/1.0",
}
page = etree.Element('rss', nsmap=nsmap)
channel = etree.SubElement(page, 'channel')
channel_title = etree.SubElement(channel, 'title')
channel_title.text = "Test RSS 2.0 data feed template products"
channel_description = etree.SubElement(channel, 'description')
channel_description.text = "test data feed template."
channel_link = etree.SubElement(channel, 'link')
channel_link.text = "https://test-abcd.com"
item = etree.SubElement(channel, "item")
item_id = etree.SubElement(item, "id", nsmap=nsmap)
item_id.text = "123456789"
return etree.tostring(page, xml_declaration=True, encoding="utf-8")
The function returns the following output:
<?xml version='1.0' encoding='utf-8'?>
<rss xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>Test RSS 2.0 data feed template products</title>
<description>test data feed template.</description>
<link>https://test-abcd.com</link>
<item>
<id>123456789</id>
</item>
</channel>
</rss>
but it should be as the following (<g:id>123456789</g:id>) :
<?xml version='1.0' encoding='utf-8'?>
<rss xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>Test RSS 2.0 data feed template products</title>
<description>test data feed template.</description>
<link>https://test-abcd.com</link>
<item>
<g:id>123456789</g:id>
</item>
</channel>
</rss>
I have found the solution which is to use etree.QName() to build the qualified name for id:
def generate_xml(self):
nsmap = {
"g": "http://base.google.com/ns/1.0",
}
page = etree.Element('rss', nsmap=nsmap)
channel = etree.SubElement(page, 'channel')
channel_title = etree.SubElement(channel, 'title')
channel_title.text = "Test RSS 2.0 data feed template products"
channel_description = etree.SubElement(channel, 'description')
channel_description.text = "test data feed template."
channel_link = etree.SubElement(channel, 'link')
channel_link.text = "https://test-abcd.com"
item = etree.SubElement(channel, "item")
item_id = etree.SubElement(item, etree.QName(nsmap.get("g"), 'id'))
item_id.text = "123456789"
return etree.tostring(page, xml_declaration=True, encoding="utf-8")

How to insert XML to SQL

I try to add a XML file to SQL 2008.
My XML:
<ItemList>
<Section Index="0" Name="cat0">
<Item Index="0" Slot="0" />
<Item Index="1" Slot="0" />
</Section>
<Section Index="1" Name="cat1">
<Item Index="33" Slot="0" />
<Item Index="54" Slot="0" />
</Section>
<Section Index="2" Name="cat2">
<Item Index="55" Slot="0" />
<Item Index="78" Slot="0" />
</Section>
</ItemList>
SQL Column :
Name = Section Name,
Cat = Section Index,
Index = Item Index,
Slot = Item Slot.
My Example :
DECLARE #input XML = 'MY XML file'
SELECT
Name = XCol.value('#Index','varchar(25)'),
Cat = XCol.value('#Name','varchar(25)'),
[Index] = 'Unknown', /* Index from <Item>*/
Slot = 'Unknown' /* Slot from <Item> */
FROM #input.nodes('/ItemList/Section') AS test(XCol)
I don't know how to add values from "Item".
Thank you very much!
You can do it like this:
select
Name = XCol.value('../#Index','varchar(25)'),
Cat = XCol.value('../#Name','varchar(25)'),
[Index] = XCol.value('#Index','varchar(25)'),
Slot = XCol.value('#Slot','varchar(25)')
from
#input.nodes('/ItemList/Section/Item') AS test(XCol)
Key idea: take data one level deeper, not /ItemList/Section, but /ItemList/Section/Item. So in this case you are able to access attributes of Item and also you can access attributes of parent element (Section in your case) by specifying ../#Attribute_Name
Different than the previous answer - CROSS APPLY with the children Item nodes:
SELECT
Name = XCol.value('#Index','varchar(25)'),
Cat = XCol.value('#Name','varchar(25)'),
[Index] = XCol2.value('#Index','varchar(25)'),
Slot = XCol2.value('#Slot','varchar(25)')
FROM #input.nodes('/ItemList/Section') AS test(XCol)
CROSS APPLY XCol.nodes('Item') AS test2(XCol2)

Dynamics CRM- update record of contact entity

I have created contact record using ASP.NET. Now I need to Check if the contact record exists. If exists, update the same record. Through advance find have downloaded FetchXML and added to my FetchXML variable. Please suggest the logic. Below is my code.
// Establish a connection to crm and get the connection proxy
string connectionString = "xyz; Username= xyz ;Password=xyz";
CrmConnection connect = CrmConnection.Parse(connectionString);
OrganizationService service;
using (service = new OrganizationService(connect))
{
WhoAmIRequest request = new WhoAmIRequest();
Guid userId = ((WhoAmIResponse)service.Execute(request)).UserId;
ContactDetails contact = new ContactDetails();
//Check if the contact record exists . If exists , update the same record.
//Fecthxml query
string fetchXml = #" <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='contact'>
<attribute name='fullname' />
<attribute name='parentcustomerid' />
<attribute name='telephone1' />
<attribute name='emailaddress1' />
<attribute name='contactid' />
<order attribute='fullname' descending='false' />
<filter type='and'>
<condition attribute= 'mobilephone' operator='not-null' />
</filter>
</entity>
</fetch>" ;
FetchExpression query = new FetchExpression(fetchXml);
EntityCollection results = service.RetrieveMultiple(query);
if (results.Entities.Count > 0)
{
Entity contactRecord = results[0];
contactRecord["firstname"] = contactInfo.FirstName;
contactRecord["lastname"] = contactInfo.LastName;
contactRecord["emailaddress1"] = contactInfo.EmailId;
contactRecord["mobilephone"] = contactInfo.MobilePhone;
contactRecord["address1_line1"] = contactInfo.Street1;
contactRecord["address1_line2"] = contactInfo.Street2;
contactRecord["address1_line3"] = contactInfo.Street3;
contactRecord["address1_city"] = contactInfo.City;
service.Update(contactRecord);
}
//Else, Create the contact record
else
{
Entity entity = new Entity();
entity.LogicalName = "contact";
entity["firstname"] = contactInfo.FirstName;
entity["lastname"] = contactInfo.LastName;
entity["emailaddress1"] = contactInfo.EmailId;
entity["mobilephone"] = contactInfo.MobilePhone;
entity["address1_line1"] = contactInfo.Street1;
entity["address1_line2"] = contactInfo.Street2;
entity["address1_line3"] = contactInfo.Street3;
entity["address1_city"] = contactInfo.City;
entity["address1_stateorprovince"] = contactInfo.State;
entity["address1_country"] = contactInfo.Country;
entity["spousesname"] = contactInfo.SpouseName;
entity["birthdate"] = contactInfo.Birthday;
entity["anniversary"] = contactInfo.Anniversary;
//Create entity gender with option value
if (contactInfo.Gender == "Male")
{
entity["gendercode"] = new OptionSetValue(1);
}
else
{
entity["gendercode"] = new OptionSetValue(2);
}
//entity["familystatuscode"] = contactInfo.MaritalStatus;
if (contactInfo.MaritalStatus == "Single")
{
entity["familystatuscode"] = new OptionSetValue(1);
}
else
{
entity["familystatuscode"] = new OptionSetValue(2);
}
service.Create(entity);
}
}
// Create the entity
your logic seems ok, with the exception of the FectchXML query. The way you have your code, you will always end up updating the first record retrieved that has its mobilephone field filled. That does not seem a good way to check if a contact already exists.
I suggest you to change the filter of your fetch. In your filter condition you have to use an attribute that represents uniqueness for all contacts.
Apart of this your code looks ok.
Like nunoalmeieda says, you need to have a better way to ascertain if the Contact already exists. A common way of identifying if the Contact already exists would be to check if the email address already exists as it is very unlikely that two people will have the same email address.
I have updated your basic code to show how it is done with FetchXML.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="contact">
<attribute name='fullname' />
<attribute name='parentcustomerid' />
<attribute name='telephone1' />
<attribute name='emailaddress1' />
<attribute name='contactid' />
<order attribute="fullname" descending="false" />
<filter type="and">
<condition attribute="emailaddress1" operator="eq" value=contactInfo.EmailId />
</filter>
</entity>
</fetch>
The logic here is that I am checking if the value of emailaddress1 (field in the contact entity of CRM) is equal to the value of your contactInfo.EmailId. I am assuming that contactInfo is the record that you get from ASP.NET.
The rest of your code is fine (I have formatted it a bit to make the question more readable).

DbUnit Assertion floating-point numbers

I'm testing my DAO layer using DbUnit. I'm prefilling database from XML dataset, doing some actions and then asserting against known result.
Assertion.assertEquals(expectedDataSet, actualDataSet);
Dataset contains column with floating point number. Then these columns are compared, I get:
junit.framework.ComparisonFailure: value (table=OrderLine_T, row=2, col=price) expected:<2.99[]> but was:<2.99[0000009536743]>.
The values are equal, but because floating-point numbers cannot be exactly represented in binary form, the assertion fails.
In JUnit we have assertEquals(double expected, double actual, double delta). How do we set some delta in DbUnit for floating-point number comparison ?
Initial dataset:
<dataset>
<Customer_T id="1" name="Anthony"/>
<Customer_T id="2" name="John"/>
<Order_T id="1" date="2012-06-07 14:30" customer_id="1" />
<Order_T id="2" date="2012-06-07 15:31" customer_id="2" />
<OrderLine_T id="1" order_id="1" product_id="1" price="2.99" quantity="5" />
<OrderLine_T id="2" order_id="2" product_id="2" price="3.49" quantity="10" />
</dataset>
Expected result:
<dataset>
<Customer_T id="1" name="Anthony"/>
<Customer_T id="2" name="John"/>
<Order_T id="1" date="2012-06-07 14:30" customer_id="1" />
<Order_T id="2" date="2012-06-07 15:31" customer_id="2" />
<OrderLine_T id="1" order_id="1" product_id="1" price="2.99" quantity="5" />
<OrderLine_T id="2" order_id="2" product_id="2" price="3.49" quantity="10" />
<!-- Below added -->
<Order_T id="3" date="1987-06-07 9:15:10" customer_id="2" />
<OrderLine_T id="3" order_id="3" product_id="1" price="2.99" quantity="2" />
<OrderLine_T id="4" order_id="3" product_id="5" price="3.55" quantity="8" />
</dataset>
Code:
/* Should save order correctly (including order lines) */
#Test
public void save() throws Exception {
/* Create new order */
Set<OrderLine> lines = new HashSet<OrderLine>();
lines.add(new OrderLine(1, (float)2.99, 2));
lines.add(new OrderLine(5, (float)3.55, 8));
Calendar cal = Calendar.getInstance();
cal.set(1987, 6, 7, 9, 15, 10);
Date date = cal.getTime();
Customer customer = customerDAO.findById(2); // John
Order order = new Order(date, lines, customer);
orderDAO.save(order);
entityManager.flush();
/* Assert order is saved */
IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream("data-set-afterAddOrder.xml"));
IDataSet actualDataSet = getDatabaseConnection().createDataSet();
Assertion.assertEquals(expectedDataSet, actualDataSet);
}
Edit:
Probably need to mention what I'm using in-memory HSQLDB. Just tried MySQL and it passes successfully.
Tried setting ToleratedDelta without success:
IDatabaseConnection connection = new DatabaseConnection(((SessionImpl) (entityManager.getDelegate())).connection());
HsqldbDataTypeFactory dataTypeFactory = new HsqldbDataTypeFactory();
dataTypeFactory.addToleratedDelta(new ToleratedDelta("OrderLine_T", "price", 0.01));
connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, dataTypeFactory);
Edit2:
I was using hibernate.hbm2ddl.auto = create, to export schema to database. After got idea from fredt, I changed the type of field price on my entity to BigDecimal and added additional column precision and scale params:
#Column(precision=10, scale=4)
private BigDecimal price;
This gets translated to PRICE NUMERIC(10,4). Problem solved, thanks to fredt.
If the column is defined as DECIMAL or NUMERIC with the required precision and scale, the value will have the exace number of digits after the decimal point and the issue can be avoided.

Tips for finding prefixed tags in python lxml?

I am trying to using lxml's ElementTree etree to find a specific tag in my xml document.
The tag looks as follows:
<text:ageInformation>
<text:statedAge>12</text:statedAge>
</text:ageInformation>
I was hoping to use etree.find('text:statedAge'), but that method does not like 'text' prefix.
It mentions that I should add 'text' to the prefix map, but I am not certain how to do it. Any tips?
Edit:
I want to be able to write to the hr4e prefixed tags.
Here are the important parts of the document:
<?xml version="1.0" encoding="utf-8"?>
<greenCCD xmlns="AlschulerAssociates::GreenCDA" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hr4e="hr4e::patientdata" xsi:schemaLocation="AlschulerAssociates::GreenCDA green_ccd.xsd">
<header>
<documentID root="18c41e51-5f4d-4d15-993e-2a932fed720a" />
<title>Health Records for Everyone Continuity of Care Document</title>
<version>
<number>1</number>
</version>
<confidentiality codeSystem="2.16.840.1.113883.5.25" code="N" />
<documentTimestamp value="201105300211+0800" />
<personalInformation>
<patientInformation>
<personID root="2.16.840.1.113883.3.881.PI13023911" />
<personAddress>
<streetAddressLine nullFlavor="NI" />
<city>Santa Cruz</city>
<state nullFlavor="NI" />
<postalCode nullFlavor="NI" />
</personAddress>
<personPhone nullFlavor="NI" />
<personInformation>
<personName>
<given>Benjamin</given>
<family>Keidan</family>
</personName>
<gender codeSystem="2.16.840.1.113883.5.1" code="M" />
<personDateOfBirth value="NI" />
<hr4e:ageInformation>
<hr4e:statedAge>9424</hr4e:statedAge>
<hr4e:estimatedAge>0912</hr4e:estimatedAge>
<hr4e:yearInSchool>1</hr4e:yearInSchool>
<hr4e:statusInSchool>attending</hr4e:statusInSchool>
</hr4e:ageInformation>
</personInformation>
<hr4e:livingSituation>
<hr4e:homeVillage>Putney</hr4e:homeVillage>
<hr4e:tribe>Oromo</hr4e:tribe>
</hr4e:livingSituation>
</patientInformation>
</personalInformation>
The namespace prefix must be declared (mapped to an URI) in the XML document. Then you can use the {URI}localname notation to find text:statedAge and other elements. Something like this:
from lxml import etree
XML = """
<root xmlns:text="http://example.com">
<text:ageInformation>
<text:statedAge>12</text:statedAge>
</text:ageInformation>
</root>"""
root = etree.fromstring(XML)
ageinfo = root.find("{http://example.com}ageInformation")
age = ageinfo.find("{http://example.com}statedAge")
print age.text
This will print "12".
Another way of doing it:
ageinfo = root.find("text:ageInformation",
namespaces={"text": "http://example.com"})
age = ageinfo.find("text:statedAge",
namespaces={"text": "http://example.com"})
print age.text
You can also use XPath:
age = root.xpath("//text:statedAge",
namespaces={"text": "http://example.com"})[0]
print age.text
I ended up having to use nested prefixes:
from lxml import etree
XML = """
<greenCCD xmlns="AlschulerAssociates::GreenCDA" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hr4e="hr4e::patientdata" xsi:schemaLocation="AlschulerAssociates::GreenCDA green_ccd.xsd">
<personInformation>
<hr4e:ageInformation>
<hr4e:statedAge>12</hr4e:statedAge>
</hr4e:ageInformation>
</personInformation>
</greenCCD>"""
root = etree.fromstring(XML)
#root = etree.parse("hr4e_patient.xml")
ageinfo = root.find("{AlschulerAssociates::GreenCDA}personInformation/{hr4e::patientdata}ageInformation")
age = ageinfo.find("{hr4e::patientdata}statedAge")
print age.text