barrycarey / SnipeSharp

A c# wrapper for the Snipe IT API
25 stars 30 forks source link

How to Checkout an Asset #7

Open Mark-Clegg opened 6 years ago

Mark-Clegg commented 6 years ago

Hi

I'm trying to checkout an Asset to a user, but can't work out the correct procedure.

I have successfully found both the Asset and the User using UserManager.FindAll and AssetManager.FindAll, but am struggling to Checkout the asset to the user.

This is what I have tried...

Asset.CheckoutRequest = new SnipeSharp.Endpoints.EndpointHelpers.AssetCheckoutRequest
{
    CheckoutToType = "user",  // Is this correct?
    AssignedUser = User,
    Note = "Auto Checkout via Easy Assist"
};
var x = snipe.AssetManager.Update(Asset);
var y = snipe.AssetManager.Checkout(Asset);

After this, x contains "success", but y is an error...

{[assigned_user, The assigned user field is required when none of assigned asset / assigned location are present.]} {[assigned_asset, The assigned asset field is required when none of assigned user / assigned location are present.]} {[assigned_location, The assigned location field is required when none of assigned user / assigned asset are present.]} {[checkout_to_type, The checkout to type field is required.]}

In the apache logs I can see that the checkout request has been received by the snipeit server, so I'm guessing I'm not preparing the request properly.

I'm also not sure if I should be Updating the asset before checking out

Any help would be appreciated. Thanks in advance Mark.

azmcnutt commented 6 years ago

Hi Mark. Did you ever figure out the trick to checking out an asset to a location?

James

barrycarey commented 6 years ago

This is probably a problem in my code. The checkout to location was added after my last update to SnipeSharp.

I'll try to dig into it and fix soon. I've been heavily tied up with work the last few months.

azmcnutt commented 5 years ago

Thank Barry. I know how the 9-5 can go.... It's about the same for me. Passion projects are hard to work on after 10 to 12 hours of staring at a computer and holding user's hands..... Then get home and do it some more.

If it helps here is where I am:

This is the code I am using to setup the checkout:

Asset myasset = snipe.AssetManager.Get(3);
myasset.CheckoutRequest = new SnipeSharp.Endpoints.EndpointHelpers.AssetCheckoutRequest()
{
    CheckoutToType = "Location",
    AssignedLocation = snipe.LocationManager.Get(2)
};

Now if I call: snipe.AssetManager.Checkout(myasset); Nothing seem to happen. But if I call for an Update using: snipe.AssetManager.Update(myasset); I get the errors below, but the transaction goes through. So I am not sure if the error is caused because I am using the wrong method or if because the wrapper is getting unexpected data. I also seem to get the same result if the checkout type is a user.

Here are the details of the error: In ResponsePayloadConverter.cs on line 64 (if (dictionary.ContainsKey("asset_teg") block) the program gives this error: Newtonsoft.Json.JsonSerializationException: Error converting value 2 to type 'SnipeSharp.Endpoints.Models.User'. Path 'assigned_to', line 1, position 218. (If you would like the stack trace, let me know)

dictionary = {{ "id": 3, "name": "Test2", "asset_tag": "01003", "model_id": 2, "serial": null, "purchase_date": null, "purchase_cost": null, "order_number": null, "assigned_to": 2, "notes": null, "image": null, "user_id": 1, "created_at": "2018-07-04 11:37:13", "updated_at": "2018-07-05 07:59:35", "physical": 1, "deleted_at": null, "status_id": 2, "archived": 0, "warranty_months": null, "depreciate": 0, "supplier_id": null, "requestable": 0, "rtd_location_id": null, "_snipeit_ethernet_mac_address_1": "01:23:45:67:89:ab", "accepted": null, "last_checkout": "2018-07-05 07:59:35", "expected_checkin": null, "company_id": 0, "assigned_type": "App\Models\Location", "last_audit_date": null, "next_audit_date": null, "location_id": 2, "checkin_counter": 4, "checkout_counter": 7, "requests_counter": 0, "_snipeit_funding_source_2": "", "_snipeit_wireless_mac_address_3": "", "assigned": { "id": 2, "name": "Kitchen", "city": "", "state": "", "country": "", "created_at": "2018-07-03 22:50:20", "updated_at": "2018-07-03 22:50:20", "address": "", "address2": "", "zip": "", "deleted_at": null, "parent_id": 1, "currency": "", "ldap_ou": null, "manager_id": 0, "image": null }}}

item= {{ "id": 3, "name": "Test2", "asset_tag": "01003", "model_id": 2, "serial": null, "purchase_date": null, "purchase_cost": null, "order_number": null, "assigned_to": 2, "notes": null, "image": null, "user_id": 1, "created_at": "2018-07-04 11:37:13", "updated_at": "2018-07-05 07:59:35", "physical": 1, "deleted_at": null, "status_id": 2, "archived": 0, "warranty_months": null, "depreciate": 0, "supplier_id": null, "requestable": 0, "rtd_location_id": null, "_snipeit_ethernet_mac_address_1": "01:23:45:67:89:ab", "accepted": null, "last_checkout": "2018-07-05 07:59:35", "expected_checkin": null, "company_id": 0, "assigned_type": "App\Models\Location", "last_audit_date": null, "next_audit_date": null, "location_id": 2, "checkin_counter": 4, "checkout_counter": 7, "requests_counter": 0, "_snipeit_funding_source_2": "", "_snipeit_wireless_mac_address_3": "", "assigned": { "id": 2, "name": "Kitchen", "city": "", "state": "", "country": "", "created_at": "2018-07-03 22:50:20", "updated_at": "2018-07-03 22:50:20", "address": "", "address2": "", "zip": "", "deleted_at": null, "parent_id": 1, "currency": "", "ldap_ou": null, "manager_id": 0, "image": null }}}

If I press continue I get the same error message in EndPointManager.cs at line 150.

I have not had a chance to trace back the wrapper to see why it is throwing that error - I suspect it is because I am using the update function to checkout an asset instead of using the checkout function.

If there is anything you would like me to try or anyway I can help, please let me know.

Thanks, James

Mark-Clegg commented 5 years ago

I'm not checking out to a location, but to a user. I abandoned the above method, and called the snipe.AssetManager.Checkout function instead, but I found that the AssetCheckoutRequest had a problem. What I did was override that with...

using SnipeSharp.Common;
using SnipeSharp.Endpoints.Models;

namespace SnipeSharpCheckoutPatch.Endpoints.EndpointHelpers
{
    public class AssetCheckoutRequest : CommonEndpointModel     // INHERITED CommonEndpointModel
    {
        [RequestHeader("checkout_to_type", true)]
        public string CheckoutToType { get; set; }

        [RequestHeader("assigned_location")]
        public Location AssignedLocation { get; set; }

        [RequestHeader("assigned_asset")]
        public Asset AssignedAsset { get; set; }

        [RequestHeader("assigned_user")]
        public User AssignedUser { get; set; }

        [RequestHeader("note")]
        public string Note { get; set; }

        // TODO: Make this a date object
        [RequestHeader("expected_checkin")]
        public string ExpectedCheckin { get; set; }

        // TODO: Make this a date object
        [RequestHeader("checkout_at")]
        public string CheckoutAt { get; set; }

        [RequestHeader("name", false)]                          // OVERRIDE Name Property to make non-mandatory
        public new string Name { get; set; }
    }
}

.. so that I didn't have to provide a name. Then used this to checkout the asset.

var CheckoutRequest = new SnipeSharpCheckoutPatch.Endpoints.EndpointHelpers.AssetCheckoutRequest
                                        {
                                            Id = Asset.Id,
                                            CheckoutToType = "user",
                                            AssignedUser = User,
                                            Note = "Some comment"
                                        };

                                        var CheckoutResult = snipe.AssetManager.Checkout(CheckoutRequest);

Hope that makes sense.

barrycarey commented 5 years ago

Hey, thanks for the info.

I just tested this out and it actually works as is.

The below code checks out the asset to the proper user.

Asset asset = snipe.AssetManager.Get(1);
asset.CheckoutRequest = new AssetCheckoutRequest()
{
      CheckoutToType = "user",
      AssignedUser = snipe.UserManager.Get(4)
 };

var result = snipe.AssetManager.Checkout(asset);

If you save the result of .Checkout to a variable you can check the status, either error or success along with the message.

However, the error you getting when calling update does appear to be a bug. It breaks the JSON converter when their is an checkout request attached. Working on that one now. Trying to wrap my head back around the code, hardly remember how it works.

azmcnutt commented 5 years ago

Hi Barry. Finally got some time to work on this again. Thanks for your code, I see what I was doing wrong now. When I was setting the CheckoutToType, I was setting it to "Location". Changing the type to "location" (lower case L) did the trick. Had I check the error message I think it would have pointed my in the right direction.

Thanks, James

Metal-Frog commented 5 years ago

Hi guys, let me first thank you for your great work. I was looking for a ITAM solution I can run on a hosted web space. After evaluating a lot of stuff I came to snipe-it. The only thing I was missing is an "agent" that automatically adds the computer it is running as an asset. So I wrote my own with the great luck of this library.

I've added the asset and tried to check it out to a location with the folllowing code:

sNewAsset.CheckoutRequest = new AssetCheckoutRequest()
            {
                CheckoutToType = "location",
                AssignedLocation = sLoc
            };
            ret = sapi.AssetManager.Checkout(sNewAsset);

This results in an error that says that an attribute field is required if none of the following values are set. But there is no name of an attribute nor any value. The full german text is:

error: Das: Attributfeld ist erforderlich, wenn keine der folgenden Werte vorhanden sind:.

Any ideas?

Best regards, Tom