I have created an iFlow to fetch the PDF documents from S4:
Unfortunately, it is returning the following response:
<?xml version='1.0' encoding='UTF-8'?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code>BAD_REQUEST</code>
<message xml:lang="en">Operation not supported</message>
</error>
Still, the iFlow was processed on CPI successfully and the output was mapped as expected. I, therefore, expect the error within the communication layer between CPI and Commerce Cloud. I use ODATA services and registered a simple EDMX with the following structure:
<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0">
<edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="2.0">
<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" xmlns:s="http://schemas.sap.com/commerce" Namespace="HybrisCommerceOData" s:schema-version="1">
<EntityType Name="Invoice">
<Key>
<PropertyRef Name="integrationKey"/>
</Key>
<Property Name="invoiceNumber" Nullable="true" Type="Edm.String" s:IsUnique="true"/>
<Property Name="integrationKey" Nullable="false" Type="Edm.String" s:Alias="Invoice_invoiceNumber"/>
</EntityType>
<EntityType Name="CoClPdfDocument">
<Key>
<PropertyRef Name="MessageId"/>
</Key>
<Property Name="MessageId" Nullable="false" Type="Edm.String" />
<Property Name="Message" Nullable="true" Type="Edm.String" />
<Property Name="Code" Nullable="true" Type="Edm.String" />
<Property Name="PDF" Nullable="false" Type="Edm.String" />
</EntityType>
<EntityContainer Name="Container" m:IsDefaultEntityContainer="true">
<EntitySet EntityType="HybrisCommerceOData.Invoice" Name="Invoices"/>
<EntitySet EntityType="HybrisCommerceOData.CoClPdfDocument" Name="Documents" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
In request fills the Invoice entity by giving the document number from the ERP. The result from the ERP fetch is written successfully into the CoClPdfDocument entity. Afterwards the process completes with message "successful", but the response I get in Postman still contains the error above.
What am I missing?
The client is pushing Time Entries through Web Service Endpoints. Client is using PHP. I have created the .Net project for only Create Time Entry, but it never came back when Push, and HTTPClient is throwing exception "The task has been cancelled.".
Here is the PHP code for creating timeentry-
<?php
require('config.php');
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client as Guzzle;
use GuzzleHttp\Cookie\CookieJar;
$cookies = new CookieJar();
define('AUTH', [
'name' => USERNAME,
'password' => PASSWORD,
'company' => COMPANY,
'branch' => BRANCH
]);
login($cookies);
$timeEntry = makeTimeEntryArray();
// $acumaticaNoteID = sendTimeEntryToAcumatica($timeEntry, $cookies);
// $timeEntry['NoteID'] = ['value' => $acumaticaNoteID];
$timeEntry['NoteID'] = ['value' => 'e5eefc3b-7750-e711-8130-129da5b884cd'];
$timeEntry['BillableTime']['value'] = '0300';
$timeEntry['TimeSpent']['value'] = '0300';
$entityId = setTimeEntryStatusToOpen($timeEntry, $cookies);
$timeEntry['id'] = $entityId;
updateTimeEntryInAcumatica($timeEntry, $cookies);
$entityId = setTimeEntryStatusToOpen($timeEntry, $cookies);
$timeEntry['id'] = $entityId;
deleteTimeEntryInAcumatica($timeEntry, $cookies);
logout($cookies);
echo "Finished Create, Update, and Delete\n";
function makeTimeEntryArray()
{
return [
'NoteID' => ['value' => null],
'Note' => ['value' => 'created by me'],
'Billable' => ['value' => true],
'BillableOvertime' => ['value' => '0000'],
'BillableTime' => ['value' => '0200'],
'Date' => ['value' => '2017-06-13T08:30:00-05:00'],
'EarningType' => ['value' => 'RG'],
'Overtime' => ['value' => '0000'],
'Owner' => ['value' => EMPLOYEE_ID],
'RelatedEntityDescription' => ['value' => ORDER_TYPE . ', ' . ORDER_NUMBER],
'Status' => ['value' => 'Completed'],
'Summary' => ['value' => 'Test Time Entry From PHP Sample Code'],
'TimeSpent' => ['value' => '0200'],
'TrackTime' => ['value' => true],
'Type' => ['value' => 'TE'],
'TypeDescription' => ['value' => 'Time Entry'],
'RefNoteID' => ['value' => ORDER_NOTE_ID],
];
}
function login($cookies)
{
echo "-----------------------------------\n";
echo date('H:i:s') . " Logging in, estimated 1s...\n";
$start = microtime(true);
$resource = '<URL>/auth/login';
echo " url: $resource\n";
$guzzle = new Guzzle();
$response = $guzzle->request('POST', $resource, [
'json' => AUTH,
'cookies' => $cookies,
'content-type' => 'application/json',
'http_errors' => false
]);
$elapsed = microtime(true) - $start;
$code = $response->getStatusCode();
if ($code == 200 || $code == 204) {
echo "Success logging in after {$elapsed}s\n";
return;
} else {
throw new Exception("Error {$code} logging in after {$elapsed}s");
}
}
function sendTimeEntryToAcumatica($data, $cookies)
{
echo "-----------------------------------\n";
echo date('H:i:s') . " Attempting to create, estimated 300s...\n";
$start = microtime(true);
$resource = '<URL>/6.00.001/TimeEntry';
$dataJson = json_encode($data);
echo " url: $resource\n";
echo " data: " . json_encode($data) . "\n";
$guzzle = new Guzzle();
$response = $guzzle->request('PUT', $resource, [
'json' => $data,
'cookies' => $cookies,
'content-type' => 'application/json',
'http_errors' => false,
]);
$elapsed = microtime(true) - $start;
$code = $response->getStatusCode();
if ($code == 200 || $code == 204) {
echo "Success creating time entry after {$elapsed}s\n";
$responseJson = json_decode($response->getBody(), true);
$acumaticaNoteID = $responseJson['NoteID']['value'];
return $acumaticaNoteID;
} else {
throw new Exception("Error {$code} creating time entry after {$elapsed}s: {$response->getBody()}");
}
}
function setTimeEntryStatusToOpen($data, $cookies)
{
echo "-----------------------------------\n";
echo date('H:i:s') . " Opening time entry...\n";
$start = microtime(true);
$updateParams = [
'NoteID' => ['value' => $data['NoteID']['value']],
'Status' => ['value' => 'Open'],
];
$resource = '<URL>/6.00.001/TimeEntry';
echo " url: $resource\n";
echo " data: " . json_encode($updateParams) . "\n";
$guzzle = new Guzzle();
$response = $guzzle->request('PUT', $resource, [
'json' => $updateParams,
'cookies' => $cookies,
'content-type' => 'application/json',
'http_errors' => false,
]);
$responseBody = $response->getBody();
$responseData = json_decode($responseBody);
$elapsed = microtime(true) - $start;
$code = $response->getStatusCode();
if ($code == 200 || $code == 204) {
if (array_key_exists('id', $responseData)) {
echo "Success opening time entry after {$elapsed}s\n";
return $responseData->id;
} else {
echo "Expected Acumatica to return an id for the time entry. Response: {$responseBody}\n";
throw new Exception("Expected Acumatica to return an id");
}
} else {
throw new Exception("Error {$code} opening time entry after {$elapsed}s. Response: {$responseBody}");
}
}
function updateTimeEntryInAcumatica($data, $cookies)
{
echo "-----------------------------------\n";
echo date('H:i:s') . " Updating time entry...\n";
$start = microtime(true);
$resource = '<URL>/6.00.001/TimeEntry';
echo " url: $resource\n";
echo " data: " . json_encode($data) . "\n";
$guzzle = new Guzzle();
$response = $guzzle->request('PUT', $resource, [
'json' => $data,
'cookies' => $cookies,
'content-type' => 'application/json',
'http_errors' => false,
]);
$responseBody = $response->getBody();
$elapsed = microtime(true) - $start;
$code = $response->getStatusCode();
if ($code == 200 || $code == 204) {
echo "Success updating time entry after {$elapsed}s\n";
} else {
throw new Exception("Error {$code} updating time entry after {$elapsed}s. Response: {$responseBody}");
}
}
function deleteTimeEntryInAcumatica($data, $cookies)
{
echo "-----------------------------------\n";
echo date('H:i:s') . " Deleting time entry...\n";
$start = microtime(true);
$resource = "<URL>/6.00.001/TimeEntry/{$data['id']}";
echo " url: $resource\n";
$guzzle = new Guzzle();
$response = $guzzle->request('DELETE', $resource, [
'cookies' => $cookies,
'content-type' => 'application/json',
'http_errors' => false,
]);
$elapsed = microtime(true) - $start;
$code = $response->getStatusCode();
$json = json_encode($response);
if ($code == 200 || $code == 204) {
echo "Success deleting time entry after {$elapsed}s\n";
} else {
throw new Exception("Error {$code} deleting time entry after {$elapsed}s. Response: {$json}");
}
}
function logout($cookies)
{
echo "-----------------------------------\n";
echo date('H:i:s') . " Logging out...\n";
$start = microtime(true);
$resource = '<URL>/auth/logout';
echo " url: $resource\n";
$guzzle = new Guzzle();
$response = $guzzle->request('POST', $resource, [
'cookies' => $cookies,
'http_errors' => false
]);
$elapsed = microtime(true) - $start;
$code = $response->getStatusCode();
$json = json_encode($response);
if ($code == 200 || $code == 204) {
echo "Success logging out after {$elapsed}s\n";
return;
} else {
throw new Exception("Error {$code} logging out after {$elapsed}s. . Response: {$json}");
}
}
Unfortunately it is taking too long to process. In a nutshell, when time entries are created, updated, or deleted, we place jobs onto a queue that handles them one at a time.
Push - makes one POST to the REST API with a json payload of the Time Entry's attributes.
Delete - makes one DELETE request to the REST API with a json payload of just the timeEntry id.
Update - makes two requests, one PUT to with a json payload setting the time entry to open, and a second PUT with a payload of the time entry attributes to make the changes.
Pushes today take around 350 seconds
Delete Jobs are around 500 seconds
Update Jobs are around 550 seconds to open, 250 seconds to update
Those times are not around any of code - that's how long its waiting for a response after the call to the REST API.
Here is the log from client, including JSON payload for the Create:-
[2017-06-09 18:12:16] local.INFO: [PushTimeEntryToAcumatica] [0] Starting PushTimeEntryToAcumatica
[2017-06-09 18:12:16] local.INFO: Current job queue count: 1
[2017-06-09 18:12:16] local.INFO: [PushTimeEntryToAcumatica] [0.05] Handling timeEntry {id: 174, user: Paul Wray, order: SO300276}
[2017-06-09 18:12:16] local.INFO: login url: /entity/auth/login
[2017-06-09 18:12:17] local.INFO: Success 204 from Acumatica: test
[2017-06-09 18:12:17] local.INFO: create url: /6.00.001/TimeEntry data: {"NoteID":{"value":null},"Note":{"value":"created by me"},"Billable":{"value":true},"BillableOvertime":{"value":"0000"},"BillableTime":{"value":"0180"},"Date":{"value":"2017-06-09T08:00:00-05:00"},"EarningType":{"value":"RG"},"Overtime":{"value":"0000"},"Owner":{"value":"EMP0000096"},"RelatedEntityDescription":{"value":"SO, SO300276"},"Status":{"value":"Completed"},"Summary":{"value":"Ryder Truck Rental - Des Moines-NW 49th- Paul Wray- 3hrs"},"TimeSpent":{"value":"0180"},"TrackTime":{"value":true},"Type":{"value":"TE"},"TypeDescription":{"value":"Time Entry"},"RefNoteID":{"value":"9af5eb4f-3934-e711-812f-12e7ddd1194d"}}
[2017-06-09 18:15:30] local.INFO: Success 200 from Acumatica: {"NoteID":{"value":null},"Note":{"value":"created by me"},"Billable":{"value":true},"BillableOvertime":{"value":"0000"},"BillableTime":{"value":"0180"},"Date":{"value":"2017-06-09T08:00:00-05:00"},"EarningType":{"value":"RG"},"Overtime":{"value":"0000"},"Owner":{"value":"EMP0000096"},"RelatedEntityDescription":{"value":"SO, SO300276"},"Status":{"value":"Completed"},"Summary":{"value":"Ryder Truck Rental - Des Moines-NW 49th- Paul Wray- 3hrs"},"TimeSpent":{"value":"0180"},"TrackTime":{"value":true},"Type":{"value":"TE"},"TypeDescription":{"value":"Time Entry"},"RefNoteID":{"value":"9af5eb4f-3934-e711-812f-12e7ddd1194d"}}
[2017-06-09 18:15:30] local.INFO: [UpdateTimeEntryInAcumatica] job dispatched for timeEntry id: 174
[2017-06-09 18:15:30] local.INFO: Current job queue count: 1
[2017-06-09 18:15:30] local.INFO: Success 204 from Acumatica: test
[2017-06-09 18:15:30] local.INFO: [PushTimeEntryToAcumatica] [193.89] SUCCESS handling timeEntry id:174
[2017-06-09 18:15:30] local.INFO: [PushTimeEntryToAcumatica] [193.89] SUCCESS handling id: 174
[2017-06-09 18:15:30] local.INFO: [PushTimeEntryToAcumatica] [193.89] Finished PushTimeEntryToAcumatica in 193.89 seconds
Acumatica Request Profiler
Part of WSDL for TimeEntry Endpoint
<s:complexType name="TimeEntry">
<s:complexContent mixed="false">
<s:extension base="q4:Entity" xmlns:q4="http://www.acumatica.com/entity/Maestro/6.00.001/">
<s:sequence>
<s:element name="ActivityDetails" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Approver" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Billable" type="q4:BooleanValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="BillableOvertime" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="BillableTime" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Date" type="q4:DateTimeValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="EarningType" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Internal" type="q4:BooleanValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="NoteID" type="q4:GuidValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Overtime" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Owner" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Project" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="ProjectTask" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="ReferenceNbr" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="RefNoteID" type="q4:GuidValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="RelatedEntityDescription" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Released" type="q4:BooleanValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="StartTime" type="q4:DateTimeValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Status" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Summary" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Task" type="q4:GuidValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="TaskSummary" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="TimeSpent" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="TrackTime" type="q4:BooleanValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Type" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="TypeDescription" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
<s:element name="Workgroup" type="q4:StringValue" maxOccurs="1" minOccurs="0" nillable="true"/>
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
Endpoint Definition generated from utility-
<?xml version="1.0" encoding="IBM437"?>
<Endpoint xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Maestro" version="6.00.001" systemContractVersion="2" xmlns="http://www.acumatica.com/entity/maintenance/5.31">
<ExtendsEndpoint name="Default" version="6.00.001" />
<TopLevelEntity name="MaestroSalesOrder" screen="SO301000">
<Fields>
<Field name="AddressLine1" type="StringValue" />
<Field name="AddressLine2" type="StringValue" />
<Field name="City" type="StringValue" />
<Field name="CustomerName" type="StringValue" />
<Field name="Date" type="DateTimeValue" />
<Field name="DatePromised" type="DateTimeValue" />
<Field name="Description" type="StringValue" />
<Field name="Email" type="StringValue" />
<Field name="Hold" type="BooleanValue" />
<Field name="LicenseNumber" type="StringValue" />
<Field name="Name" type="StringValue" />
<Field name="Odometer" type="IntValue" />
<Field name="OrderNbr" type="StringValue" />
<Field name="OrderType" type="StringValue" />
<Field name="Phone1" type="StringValue" />
<Field name="PostalCode" type="StringValue" />
<Field name="State" type="StringValue" />
<Field name="Status" type="StringValue" />
<Field name="TankModel" type="StringValue" />
<Field name="TankSpec" type="StringValue" />
<Field name="TankVIN" type="StringValue" />
<Field name="TankYearMake" type="StringValue" />
<Field name="TAS" type="StringValue" />
<Field name="TRS" type="StringValue" />
<Field name="TruckModel" type="StringValue" />
<Field name="TruckVIN" type="StringValue" />
<Field name="TruckYearMake" type="StringValue" />
<Field name="UnitNumber" type="StringValue" />
</Fields>
<Mappings>
<Mapping field="AddressLine1">
<To object="Shipping_Address" field="AddressLine1" />
</Mapping>
<Mapping field="AddressLine2">
<To object="Shipping_Address" field="AddressLine2" />
</Mapping>
<Mapping field="City">
<To object="Shipping_Address" field="City" />
</Mapping>
<Mapping field="CustomerName">
<To object="Document" field="CustomerID%AcctName" />
</Mapping>
<Mapping field="Date">
<To object="Document" field="OrderDate" />
</Mapping>
<Mapping field="DatePromised">
<To object="CurrentDocument: 11" field="UsrDatePromised" />
</Mapping>
<Mapping field="Description">
<To object="Document" field="OrderDesc" />
</Mapping>
<Mapping field="Email">
<To object="Shipping_Contact" field="Email" />
</Mapping>
<Mapping field="Hold">
<To object="Document" field="Hold" />
</Mapping>
<Mapping field="LicenseNumber">
<To object="CurrentDocument: 7" field="UsrLicenseNbr" />
</Mapping>
<Mapping field="Name">
<To object="Document" field="SalesPersonID%Descr" />
</Mapping>
<Mapping field="Odometer">
<To object="CurrentDocument: 7" field="UsrOdometer" />
</Mapping>
<Mapping field="OrderNbr">
<To object="Document" field="OrderNbr" />
</Mapping>
<Mapping field="OrderType">
<To object="Document" field="OrderType" />
</Mapping>
<Mapping field="Phone1">
<To object="Shipping_Contact" field="Phone1" />
</Mapping>
<Mapping field="PostalCode">
<To object="Shipping_Address" field="PostalCode" />
</Mapping>
<Mapping field="State">
<To object="Shipping_Address" field="State%StateID" />
</Mapping>
<Mapping field="Status">
<To object="Document" field="Status" />
</Mapping>
<Mapping field="TankModel">
<To object="CurrentDocument: 9" field="UsrTankModel" />
</Mapping>
<Mapping field="TankSpec">
<To object="CurrentDocument: 9" field="UsrTankSpec" />
</Mapping>
<Mapping field="TankVIN">
<To object="CurrentDocument: 9" field="UsrTankVINInfo" />
</Mapping>
<Mapping field="TankYearMake">
<To object="CurrentDocument: 9" field="UsrTankYearMake" />
</Mapping>
<Mapping field="TAS">
<To object="CurrentDocument: 9" field="UsrTankTAS" />
</Mapping>
<Mapping field="TRS">
<To object="CurrentDocument: 10" field="UsrTruckTRS" />
</Mapping>
<Mapping field="TruckModel">
<To object="CurrentDocument: 10" field="UsrTruckModel" />
</Mapping>
<Mapping field="TruckVIN">
<To object="CurrentDocument: 10" field="UsrTruckVINInfo" />
</Mapping>
<Mapping field="TruckYearMake">
<To object="CurrentDocument: 10" field="UsrTruckYearMake" />
</Mapping>
<Mapping field="UnitNumber">
<To object="CurrentDocument: 7" field="UsrUnitNbr" />
</Mapping>
</Mappings>
</TopLevelEntity>
<TopLevelEntity name="TimeEntry" screen="CR306010">
<Fields>
<Field name="ActivityDetails" type="StringValue" />
<Field name="Approver" type="StringValue" />
<Field name="Billable" type="BooleanValue" />
<Field name="BillableOvertime" type="StringValue" />
<Field name="BillableTime" type="StringValue" />
<Field name="Date" type="DateTimeValue" />
<Field name="EarningType" type="StringValue" />
<Field name="Internal" type="BooleanValue" />
<Field name="NoteID" type="GuidValue" />
<Field name="Overtime" type="StringValue" />
<Field name="Owner" type="StringValue" />
<Field name="Project" type="StringValue" />
<Field name="ProjectTask" type="StringValue" />
<Field name="ReferenceNbr" type="StringValue" />
<Field name="RefNoteID" type="GuidValue" />
<Field name="RelatedEntityDescription" type="StringValue" />
<Field name="Released" type="BooleanValue" />
<Field name="StartTime" type="DateTimeValue" />
<Field name="Status" type="StringValue" />
<Field name="Summary" type="StringValue" />
<Field name="Task" type="GuidValue" />
<Field name="TaskSummary" type="StringValue" />
<Field name="TimeSpent" type="StringValue" />
<Field name="TrackTime" type="BooleanValue" />
<Field name="Type" type="StringValue" />
<Field name="TypeDescription" type="StringValue" />
<Field name="Workgroup" type="StringValue" />
</Fields>
<Mappings>
<Mapping field="ActivityDetails">
<To object="CurrentActivity" field="Body" />
</Mapping>
<Mapping field="Approver">
<To object="TimeActivity" field="ApproverID" />
</Mapping>
<Mapping field="Billable">
<To object="TimeActivity" field="IsBillable" />
</Mapping>
<Mapping field="BillableOvertime">
<To object="TimeActivity" field="OvertimeBillable" />
</Mapping>
<Mapping field="BillableTime">
<To object="TimeActivity" field="TimeBillable" />
</Mapping>
<Mapping field="Date">
<To object="Activities" field="StartDate_Date" />
</Mapping>
<Mapping field="EarningType">
<To object="TimeActivity" field="EarningTypeID" />
</Mapping>
<Mapping field="Internal">
<To object="Activities" field="IsPrivate" />
</Mapping>
<Mapping field="NoteID">
<To object="Activities" field="NoteID" />
</Mapping>
<Mapping field="Overtime">
<To object="TimeActivity" field="OvertimeSpent" />
</Mapping>
<Mapping field="Owner">
<To object="Activities" field="OwnerID" />
</Mapping>
<Mapping field="Project">
<To object="TimeActivity" field="ProjectID" />
</Mapping>
<Mapping field="ProjectTask">
<To object="TimeActivity" field="ProjectTaskID" />
</Mapping>
<Mapping field="ReferenceNbr">
<To object="TimeActivity" field="ARRefNbr" />
</Mapping>
<Mapping field="RefNoteID">
<To object="Activities" field="RefNoteID" />
</Mapping>
<Mapping field="RelatedEntityDescription">
<To object="Activities" field="Source" />
</Mapping>
<Mapping field="Released">
<To object="TimeActivity" field="Released" />
</Mapping>
<Mapping field="StartTime">
<To object="Activities" field="ParentNoteID%StartDate" />
</Mapping>
<Mapping field="Status">
<To object="TimeActivity" field="ApprovalStatus" />
</Mapping>
<Mapping field="Summary">
<To object="Activities" field="Subject" />
</Mapping>
<Mapping field="Task">
<To object="Activities" field="Subject" />
</Mapping>
<Mapping field="TaskSummary">
<To object="Activities" field="ParentNoteID!Subject" />
</Mapping>
<Mapping field="TimeSpent">
<To object="TimeActivity" field="TimeSpent" />
</Mapping>
<Mapping field="TrackTime">
<To object="TimeActivity" field="TrackTime" />
</Mapping>
<Mapping field="Type">
<To object="Activities" field="Type" />
</Mapping>
<Mapping field="TypeDescription">
<To object="Activities" field="Type_description" />
</Mapping>
<Mapping field="Workgroup">
<To object="Activities" field="WorkgroupID" />
</Mapping>
</Mappings>
</TopLevelEntity>
</Endpoint>
JSON Object
{
"NoteID": {
"value": null
},
"Note": {
"value": "Created by Krunal"
},
"Billable": {
"value": true
},
"BillableOvertime": {
"value": "0000"
},
"BillableTime": {
"value": "0200"
},
"Date": {
"value": "2017-06-27T08:00:00-05:00"
},
"EarningType": {
"value": "RG"
},
"Overtime": {
"value": "0000"
},
"Owner": {
"value": "EMP0000002"
},
"RelatedEntityDescription": {
"value": "SO, SO300279"
},
"Status": {
"value": "Completed"
},
"Summary": {
"value": "Test Please Ignore"
},
"TimeSpent": {
"value": "0200"
},
"TrackTime": {
"value": true
},
"Type": {
"value": "TE"
},
"TypeDescription": {
"value": "Time Entry"
},
"RefNoteID": {
"value": "052F4A9B-8635-E711-812F-12E7DDD1194D"
}
}
Response time for above request
After removing StartTime and TaskSummary
I have created a custom data list in Alfresco, and have populated its model with the desired data columns. However, when I view the list in Alfresco share, the order is completely off, and there are elements that I have not defined in the model.
I have searched extensively as to how to fix this, and have not been successful. From what I understand, I need to define the layout in the share-config-custom.xml, which I have attempted below (snippet of only what I added):
<config evaluator="model-type" condition="orpdl:orpList">
<forms>
<form>
<field-visibility>
<show id="orpdl:programName" />
</field-visibility>
<create-form template="../data-lists/forms/dataitem.ftl" />
<appearance>
<field id="orpdl:programName">
<control template="/org/alfresco/components/form/controls/textarea.ftl" />
</field>
</appearance>
</form>
</forms>
</config>
<config evaluator="node-type" condition="orpdl:orpList">
<forms>
<form>
<field-visibility>
<show id="orpdl:programName" />
</field-visibility>
<create-form template="../data-lists/forms/dataitem.ftl" />
<appearance>
<field id="orpdl:programName">
<control template="/org/alfresco/components/form/controls/textarea.ftl" />
</field>
</appearance>
</form>
</forms>
</config>
Content model:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Definition of new Model -->
<model name="orpdl:orpDataListModel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<!-- Optional meta-data about the model -->
<description>Information retrieved from the Opportunity Registration Process workflow form.</description>
<author>Alan George</author>
<version>1.0</version>
<!-- Imports are required to allow references to definitions in other models -->
<imports>
<!-- Import Alfresco Dictionary Definitions -->
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
<!-- Import Alfresco Content Domain Model Definitions -->
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
<import uri="http://www.alfresco.org/model/system/1.0" prefix="sys" />
<import uri="http://www.alfresco.org/model/datalist/1.0" prefix="dl" />
</imports>
<!-- Introduction of new namespaces defined by this model -->
<namespaces>
<namespace uri="http://www.test.com/model/orpDataListModel/1.0" prefix="orpdl" />
</namespaces>
<constraints>
<constraint name="orpdl:contractTypeList" type="LIST">
<parameter name="allowedValues">
<list>
<value>T&M</value>
<value>FFP</value>
<value>CPFF</value>
<value>CPIF</value>
</list>
</parameter>
</constraint>
</constraints>
<types>
<type name="orpdl:orpList">
<title>Opportunity Registration Process</title>
<description>Information retrieved from the Opportunity Registration Process workflow form.</description>
<parent>dl:dataListItem</parent>
<properties>
<property name="orpdl:programName">
<title>Program Name</title>
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="orpdl:programDescription">
<title>Program Description</title>
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="orpdl:client">
<title>Client</title>
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="orpdl:contractType">
<title>Contract Type</title>
<type>d:text</type>
<mandatory>true</mandatory>
<constraints>
<constraint ref="orpdl:contractTypeList" />
</constraints>
</property>
<property name="orpdl:value">
<title>Value</title>
<type>d:text</type>
<mandatory>true</mandatory>
</property>
</properties>
</type>
</types>
</model>
The goal of this code is to have only the programName text box appear. But this is what I'm seeing:
What am I missing?
You are entering wrong condition in <config> tag.
Below
<config evaluator="model-type" condition="orpdl:orpDataListModel">
should replace with
<config evaluator="model-type" condition="orpdl:issuesList">
This will also apply to node-type.
I would like to allow some of my SOAP header elements to be nillable. This is possible for body elements, but I am not sure if it is allowed from header elements.
In the sample message below, I would like to allow the MessageDateTime to be null.
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://mycompany.com/repositoryservice">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="http://mycompany.com/repositoryservice">
<element name="MessageDateTime" type="dateTime" />
<element name="SaveRequest">
<!-- complexType -->
</element>
</schema>
</types>
<message name="SaveRequest_Headers">
<part name="MessageDateTime" element="tns:MessageDateTime" />
</message>
<message name="SaveRequest">
<part name="parameters" element="tns:SaveRequest" />
</message>
<binding name="RepositoryServiceBinding" type="tns:IRepositoryService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="Save">
<soap:operation soapAction="http://mycompany.com/repositoryservice/Save" style="document" />
<input name="SaveRequest">
<soap:header message="tns:SaveRequest_Headers" part="MessageDateTime" use="literal" />
<soap:body use="literal" />
</input>
</operation>
</binding>
<!-- service, portType -->
</definitions>
It is allowed as long as the definition allows for it. In your case, all you have to do is add the nillable="true" to the element's definition. The result on .NET w/ WCF would look something like this:
[System.ServiceModel.MessageHeaderAttribute(Namespace="...")]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public System.Nullable<System.DateTime> MessageDateTime;
I have what strikes me as a very unusual behavior from Linq for NHibernate.
In general, all my entity classes are working just fine, but one of them throws a "NonUniqueResult" exception from the NHibernate namespace under the following condition.
If I call the following:
getSession<MyClass>().Linq<MyClass>().Count();
it throws the exception. If I call
getSession<MyClass>().Linq<MyClass>().ToList().Count();
it does not.
There's no problem with the other CRUD operations for this class, so I don't think it's my mappings.
My guess is that it has something to do with how the Count() operator ultimately gets materialized as a SQL query, but beyond that I'm not sure where to look.
Updated to include mapping of the class in question
<?xml version="1.0" encoding="utf-16"?>
<hibernate-mapping auto-import="true" default-lazy="false" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.2">
<class name="My.App.MyClass, My.App" table="MyClass">
<id name="Id" access="property" column="Id" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid.comb">
</generator>
</id>
<version name="TimeStamp" access="property" column="TimeStamp" type="Int32" />
<property name="CreatedOn" access="property" type="System.DateTime">
<column name="CreatedOn"/>
</property>
<property name="Ticker" access="property" type="Int32">
<column name="Ticker"/>
</property>
<property name="DifferentTicker" access="property" type="Int32">
<column name="DifferentTicker"/>
</property>
<property name="SomeDecimal" access="property" type="System.Decimal">
<column name="SomeDecimal"/>
</property>
<property name="StillAnotherTicker" access="property" type="Int32">
<column name="StillAnotherTicker"/>
</property>
<property name="IsActive" access="property" type="Boolean">
<column name="IsActive"/>
</property>
<many-to-one name="RelatedThing" access="property" class="My.App.RelatedThing, My.App" column="RelatedThingId" lazy="proxy" />
<many-to-one name="OtherRelatedThing" access="property" class="My.App.OtherRelatedThing, My.App" column="OtherRelatedThingId" lazy="proxy" />
<bag name="_schedule" access="property" table="Schedule" lazy="false" cascade="all-delete-orphan">
<key column="MyClassId" />
<one-to-many class="My.App.Schedule, My.App" />
</bag>
<bag name="Vectors" access="property" table="Vectors" lazy="false">
<key column="MyClassId" />
<many-to-many class="My.App.Channels.BaseVector, My.App" column="vectorid"/>
</bag>
</class>
</hibernate-mapping>
Both version work fine for me in a simple unit test. In this example:
using ( var tx = Session.BeginTransaction() )
{
int count = Session.Linq<Customer>().Count();
Assert.Equal( 2, count );
count = Session.Linq<Customer>().ToList().Count();
Assert.Equal( 2, count );
tx.Commit();
}
The first query performs a SQL count:
NHibernate: SELECT count(*) as y0_ FROM "Customer" this_
And the second gets all returns all items into a temporary list and then calls Count() on the list:
NHibernate: SELECT this_.Id as Id9_0_, this_.Name as Name9_0_ FROM "Customer" this_
This leads me to believe that there might be an issue with your mappings. And you really want to get the first one working cause the second won't scale for large datasets.