GithubHelp home page GithubHelp logo

dynamics_crm's Introduction

DynamicsCRM

Build Status

Ruby library for accessing Microsoft Dynamics CRM Online 2011/2013 via their SOAP API.

Installation

Add this line to your application's Gemfile:

gem 'dynamics_crm'

And then execute:

$ bundle

Or install it yourself as:

$ gem install dynamics_crm

Usage

Username/Password authentication

client = DynamicsCRM::Client.new({organization_name: "orgname"})
client.authenticate('[email protected]', 'password')

retrieve

client.retrieve('account', '53291AAB-4A9A-E311-B097-6C3BE5A8DD60')
# => #<DynamicsCRM::XML::Entity ... >

retrieve_multiple

client.retrieve_multiple('account', [["name", "Equal", "Test Account"]])
# => [#<DynamicsCRM::XML::Entity ... >]

client.retrieve_multiple('account', [["name", "Equal", "Test Account"], ['salesstage', 'In', [0, 1, 2]]])
# => [#<DynamicsCRM::XML::Entity ... >]

client.retrieve_multiple('account', [["telephone1", "EndsWith", "5558675309"], ["mobilephone", "EndsWith", "5558675309"]], [], "Or")
# => [#<DynamicsCRM::XML::Entity ... >]

retrieve_multiple using QueryExpression

# Build QueryExpression
query = DynamicsCRM::XML::QueryExpression.new('account')
query.columns = %w(accountid name)
query.criteria.add_condition('name', 'NotEqual', 'Test Account')
# Optional PageInfo
query.page_info = DynamicsCRM::XML::PageInfo.new(count: 5, page_number: 1, return_total_record_count: true)

# Get first page
result = client.retrieve_multiple(query)

while result.MoreRecords
  # Next page
  query.page_info.page_number += 1
  query.page_info.paging_cookie = result.PagingCookie

  result = client.retrieve_multiple(query)
end

retrieve_multiple using complex Filters

# Build QueryExpression
query = DynamicsCRM::XML::QueryExpression.new('account')
query.columns = %w(accountid name telephone1)
# Switch to Or criteria
query.criteria.filter_operator = 'Or'

filter1 = DynamicsCRM::XML::FilterExpression.new('And')
filter1.add_condition('name', 'Equal', 'Integration Specialists')
filter1.add_condition('telephone1', 'In', ['(317) 845-2212', '3178452212'])

filter2 = DynamicsCRM::XML::FilterExpression.new('And')
filter2.add_condition('name', 'Equal', 'Thematics Development Inc.')
filter2.add_condition('telephone1', 'Null')

# Add Filters to criteria
query.criteria.add_filter(filter1)
query.criteria.add_filter(filter2)


result = client.retrieve_multiple(query)

fetch (FetchXml)

# Raw XML Support
xml = %Q{<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
  <entity name="opportunityproduct">
    <attribute name="opportunityproductid" />
    <attribute name="productdescription" />
    <attribute name="priceperunit" />
    <attribute name="quantity" />
    <order attribute="productid" descending="false" />
    <link-entity name="product" from="productid" to="productid" alias="product" link-type="inner">
      <attribute name="name" />
      <attribute name="producttypecode" />
      <attribute name="price" />
      <attribute name="standardcost" />
    </link-entity>
    <filter type="and">
      <condition attribute="opportunityid" operator="eq" value="02dd7344-d04a-e411-a9d3-9cb654950300" />
    </filter>
  </entity>
</fetch>}

result = client.fetch(xml)
# => #<DynamicsCRM::XML::EntityCollection>
# result.entity_name => 'opportunityproduct'
# result.entities => [DynamicsCRM::XML::Entity, ...]
# Using FetchXml::Builder
builder = DynamicsCRM::FetchXml::Builder.new()

entity = builder.entity('opportunityproduct').add_attributes(
  ['productdescription', 'priceperunit', 'quantity', 'opportunityproductid']
).order('productid')

entity.link_entity('product', to: 'productid', from: 'productid', :alias => 'product').add_attributes(
  ['name', 'producttypecode', 'price', 'standardcost']
)

entity.add_condition('opportunityid', 'eq', '02dd7344-d04a-e411-a9d3-9cb654950300')

result = client.fetch(builder.to_xml)
# => #<DynamicsCRM::XML::EntityCollection>
# result.entity_name => 'opportunityproduct'
# result.entities => [DynamicsCRM::XML::Entity, ...]

create

# Add a new account
client.create('account', name: 'Foobar Inc.')
# => {id: '53291AAB-4A9A-E311-B097-6C3BE5A8DD60'}

# Add a new contact
client.create('contact', firstname: 'John', lastname: 'Doe', emailaddress1: "[email protected]")
# => {id: '71ef2416-50f7-e311-93fc-6c3be5a8c054'}

update

# Update the Account with id '53291AAB-4A9A-E311-B097-6C3BE5A8DD60'
client.update('account', '53291AAB-4A9A-E311-B097-6C3BE5A8DD60', name: 'Whizbang Corp')
# => {}

delete

# Delete the Account with id '53291AAB-4A9A-E311-B097-6C3BE5A8DD60'
client.delete('account', '53291AAB-4A9A-E311-B097-6C3BE5A8DD60')
# => {}

retrieve_all_entities

# get the list of organization entities
client.retrieve_all_entities
# => [#<DynamicsCRM::Metadata::EntityMetadata>, ...]

retrieve_entity

# get the entity metadata for the account object
client.retrieve_entity('account')
# => DynamicsCRM::Metadata::EntityMetadata

retrieve_attribute

# get AttributeMetadata for 'name' field on the account object
client.retrieve_attribute('account', 'name')
# => [#<DynamicsCRM::Metadata::AttributeMetadata>, ...]

associate a contact to an account

contacts = [ DynamicsCRM::XML::EntityReference.new("contact", contact["id"])]
client.associate("account", account["id"], "contact_customer_accounts", contacts)

Logging

If you want to log the REQUEST and RESPONSE, you can do through Logger class of Ruby.

client.logger = Logger.new(STDOUT)

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

dynamics_crm's People

Contributors

barberj avatar brunogh avatar carlos4ndre avatar danielpk avatar jheth avatar jnpoyser avatar jorlando-conga avatar kam avatar marceloalves avatar mbhnyc avatar sribalakumar avatar stephanvd avatar thekidcoder avatar wnovak-conga avatar xcoan-conga avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dynamics_crm's Issues

Accessing entities with guid only?

I have a generic integration adapter that works for both salesforce and dynamics and one irritating thing is how in Dynamics i always need to supply a type and ID β€”Β is there a way to discover the type of an object? It doesn't look like it from what I know so far, but thought I'd ask.

On premise support

Does this gem support on premise, I get 401 unauthorised response.

This is the verbose response I get :1:
< HTTP/1.1 100 Continue
< HTTP/1.1 401 Unauthorized
< Cache-Control: private
< Transfer-Encoding: chunked
< Content-Type: text/plain

  • Server Microsoft-IIS/8.5 is not blacklisted
    < Server: Microsoft-IIS/8.5
    < X-AspNet-Version: 4.0.30319
    < WWW-Authenticate: NTLM
    < WWW-Authenticate: Negotiate
    < X-Powered-By: ASP.NET
    < Date: Thu, 12 Mar 2015 00:55:32 GMT
  • HTTP error before end of send, stop sending
    <
  • Closing connection 0
    HTTP Error 401 - Unauthorized: Access is denied

RuntimeError: HTTP Error 401 - Unauthorized: Access is denied

Paging support?

Hey all - how does paging work in the gem? Is there a good example floating around?

I see the PageInfo object, but how do I make a query that uses it?

REXML gem missing

REXML seems to be a dependency, but it is not specified in the gemspec.

String in the format of a guid is automatically converted to guid type

Our Dynamics CRM partner is telling us that to reference an entity (not doing an update), we need to pass the guid as a string. Not sure how accurate that is, but it would probably be a good thing to be able to override the automatic data typing (which is actually pretty great). We are trying to have our partner convert the guid we are sending into a string for the lookup on their end but are getting push back. If they should be able to convert that on their end, I'd love to know that. That could potentially make this issue a non-issue.

We are looking at making a change to facilitate this and would love to contribute if this actually is an issue (and not just incompetence or laziness of our partner).

cannot receive all entities

Hi all,
When I try to get all CRM entities it doesn't respond array of entities
@client.retrieve_all_entities()

{"ResponseName"=>"RetrieveAllEntities", "Timestamp"=>"1956489052"}

Accessing linked entities ?

First off thanks for this wonderful gem.

Secondly, what is the most elegant way to access linked entities - without using a Builder to explicitly link them in? Iterating thru a small set using the simple retrieve_multipleand need to conditionally access linked entities.

Batching ?

Calling retrieve_multiple on a large dataset returns Curl::Err::TimeoutError: Timeout was reached.

Is there a way to retrieve_multiple in batches?

Batching ?

Calling retrieve_multiple on a large dataset returns Curl::Err::TimeoutError: Timeout was reached.

Is there a way to retrieve_multiple in batches?

Authentication Failures?

Hey all,

Have any of you dealt with authentication failure issues for some customers?

We have a customer who can't authenticate and we've tried quite a few variations on their org name, the user is a Global Admin so we don't think there's a permission issue. Does the user need any other permission we may be missing?

This may not actually be a Gem issue, if so we can close this, but once we figure out why auth is failing, maybe there's an improvement that can be made to surface a better error to developers.

Setting state on entities?

Hey all-

Is it possible to set entity state with the gem currently, docs suggest it should be editable after creation, but point to the https://msdn.microsoft.com/en-us/library/microsoft.crm.sdk.messages.setstaterequest.aspx method which i don't think we support yet.

Is this possible in a different way? Can start on a pull request to support this function, just wanted to know if i was missing anything dumb.

Seg fault on mac and resolution

It seems that if you are on a mac using the gem spring in development mode that the connection to the soap endpoint causes segmentation faults.

By removing or commenting out spring or running on a non development environment the segmentation faults do not occur.

The gem also appears to be working well with CRM 2015 update 1 which is worth mentioning to anyone who may otherwise pass it by.

Cheers and thanks!

Associate call is not associating objects

Tried to associate a contact to an account and got nil on the associate call.

contact = client.create('contact', firstname: 'Jane', lastname: 'Doe')
account = client.create('account', name: 'Foobar Inc.')
contacts = [ DynamicsCRM::XML::EntityReference.new("contact", contact["id"])]
client.associate("account", account["id"], "contact_customer_accounts", contacts)

Curb leaking sockets on Windows

After about 50 requests to CRM, the Ruby process starts failing with "Too many open files" error. I have only experienced this on Windows, and suspect this is a Windows-only issue with Curb. Even though the post method in client.rb calls close on the Curl::Easy instance, it seems to have no effect, and looking at netstat -a output you can see connections building up with each call and never closed. I tried every possible way to get Curb to close its connections to no avail.

In the end I solved this problem for myself by rewriting the post method using net/http as follows:

    require 'net/http'
    def post(url, request)
      log_xml("REQUEST", request)

      uri = URI(url)
      ssl = {
        :use_ssl => (uri.scheme == 'https'),
        :verify_mode => OpenSSL::SSL::VERIFY_NONE
      }

      response = Net::HTTP.start(uri.host, uri.port, ssl) do |http|
        req = Net::HTTP::Post.new(uri)
        req['Connection'] = 'Keep-Alive'
        req['Content-type'] = 'application/soap+xml; charset=UTF-8'
        req.body = request
        http.request(req).body
      end

      log_xml("RESPONSE", response)
      response
    end

One might say I kicked Curb to the curb :)

Since this is the only place in this gem that actually uses Curb, it is possible to drop the dependency on Curb entirely. The only reservation I have is that net/http does not follow redirects automatically. I see that in the original post method you use the follow_location feature of Curb. My experience with CRM is entirely read-only, and there has not been any need for following redirects so far. So, I don't know if CRM ever responds with a redirect - do you know of some use cases where it does? If not, I'd be happy to submit a pull request to get rid of Curb dependency in this gem. It was such a PITA to get it to work on Windows in the first place, and now this thing. I would be happy to see Curb gone :)

Interacting with activityparties?

Been trying a variety of permutations today to attach activityparties to a phonecall activity with no joy so far, here's an example of this being done:

Entity from1 = new Entity("activityparty");
Entity to1 = new Entity("activityparty");
Entity to2 = new Entity("activityparty"); // two contacts inside the to field

from1["partyid"]= new EntityReference("systemuser", userId);
to1["partyid"]= new EntityReference("contact", contact1Id);
to2["partyid"]= new EntityReference("contact", contact2Id);

Entity phonecall = new Entity("phonecall");

phonecall["from"] = new Entity[] { from1 };
phonecall["to"] = new Entity[] { to1, to2 };
// other phonecall fields
service.Create(phonecall);

Has anyone accomplished this sort of creation with the gem, or should I look into making a PR to support this type of SOAP call?

Thanks in advance!

Attribute type double support

Address latitude/longitude fields are doubles. Currently ruby BigDecimal/Float are mapped to float in Dynamics.

I'm thinking about introducing a value object to map to double. i.e. DynamicsCRM::Types::Double.new(something)

Any thoughts on supporting this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.