public CustomFieldRef[] GetOrderFields(SalesOrderRetrieveDTO salesOrder, NetSuiteApi api)
        {
            var fields = new List<CustomFieldRef> {
                new StringCustomFieldRef
                {
                    scriptId="custentity_ibushak_id", value=salesOrder.Contact.ContactPerson ?? "?"
                },
                new StringCustomFieldRef
                {
                    scriptId="otherrefnum", value=salesOrder.Id
                },
                new StringCustomFieldRef
                {
                    scriptId="custitem1", value=salesOrder.Lines.First().Product.Brand ?? "?"
                },
                new StringCustomFieldRef
                {
                    scriptId="custbody5", value=salesOrder.Lines.First().Product.Brand ?? "?"
                },
                new StringCustomFieldRef
                {
                    scriptId="shipmethod", value="DHL"
                }
            };

            if (salesOrder.HasShipments)
            {
                fields.Add(
                    new StringCustomFieldRef
                    {
                        scriptId="custbody_guia", value=salesOrder.Shipments.First().Method.TrackingNumber ?? "?"
                    }
                );
            }

            if (salesOrder.HasPayments && salesOrder.Payments.First().Integration != null)
            {
                fields.Add(
                    new StringCustomFieldRef
                    {
                        scriptId="custbody_refpag", value=salesOrder.Payments.First().Integration.IntegrationId
                    }
                );
            }

            return fields.ToArray();
        }
        /// <summary>
        /// Creates or updates a sales order. Returns the id.
        /// </summary>
        public string CreateOrUpdateSalesOrder(SalesOrderRetrieveDTO salesOrder)
        {
            var netSuiteOrder = this.generateSalesOrder(salesOrder);

            try {
                netSuiteOrder.internalId = this.getSalesOrder(salesOrder.Id).internalId;

                if (salesOrder.Date < this.api.Integration.GetLowerLimitOfDate())
                    return "";

                this.api.Query<WriteResponse>(() =>
                    this.api.Service.update(netSuiteOrder)
                );

                return this.GetSalesOrderAndCreatePayments(salesOrder);
            } catch (InstanceNotFoundException) {
                this.api.Query<WriteResponse>(() =>
                    this.api.Service.add(netSuiteOrder)
                );

                return this.GetSalesOrderAndCreatePayments(salesOrder);
            } catch (ApplicationException e)
            {
                var message = e.Message;

                if (message.Contains("have been fulfilled"))
                {
                    // TODO: Sacar este hack
                    if (this.api.Integration is IbushakIntegration)
                        return this.GetSalesOrderAndCreatePayments(salesOrder);
                    else
                        return this.getSalesOrder(salesOrder.Id).internalId;
                }

                var messages = e.Message.Split('|');
                if (messages.Any(it => it.Contains("Los pedidos numerados se confirman siempre antes que los pedidos no numerados")))
                    return "";

                throw;
            }
        }
        private string getShippingOptions(SalesOrderRetrieveDTO salesOrder)
        {
            switch (salesOrder.DeliveryMethod)
            {
                case "ToBeConfirmed":
                    return "10"; // a convenir
                case "Pickup":
                    return "9"; // retira cliente
            }

            return "11"; // mercadoenvíos
        }
        public void TransformOrder(SalesOrder netSuiteOrder, SalesOrderRetrieveDTO salesOrder, NetSuiteApi api)
        {
            netSuiteOrder.@class = new RecordRef
            {
                internalId = this.getBusinessUnit(api)
            };

            netSuiteOrder.orderStatus = SalesOrderOrderStatus._pendingFulfillment;

            // Una modificación, para la cuentas “TIENDAS STADIO” (todas las marcas, excepto Edifier) que apuntan
            // a la localización Stadio_Salta (13) deben tener la b.unit (campo class): Stadio B2C, Mercado Libre (id 10).
            if (this.getLocation(salesOrder.Lines.First(), api) == "13") // 13 = Stadio_Salta
                netSuiteOrder.@class = new RecordRef { internalId = "10" }; // Stadio B2C, Mercado Libre

            netSuiteOrder.department = new RecordRef {internalId = "18"}; // no aplica
        }
 public string GetOrderLocation(IEnumerable<dynamic> items, SalesOrderRetrieveDTO salesOrder, NetSuiteApi api)
 {
     return this.getLocation(salesOrder.Lines.First(), api);
 }
        public CustomFieldRef[] GetOrderFields(SalesOrderRetrieveDTO salesOrder, NetSuiteApi api)
        {
            var fields = new List<CustomFieldRef>
            {
                new StringCustomFieldRef
                {
                    scriptId = "custbody_opcionesenvio",
                    value = this.getShippingOptions(salesOrder)
                },
                new StringCustomFieldRef
                {
                    scriptId = "custbody_3k_store_web",
                    value = api.Credentials.AccountName
                }
            };

            if (salesOrder.HasShipments)
            {
                var shipment = salesOrder.Shipments.First();

                fields.Add(new StringCustomFieldRef
                {
                    scriptId = "custbody_3k_proveedor_envio",
                    value = this.getShippingProvider(shipment, api)
                });

                fields.Add(new StringCustomFieldRef
                {
                    scriptId = "custbody_3k_link_etiqueta_envio",
                    value = "http://mercadolibre.azurewebsites.net/shipments/label/pdf?access_token=" + api.Credentials.ProductecaToken + "&ids=" + shipment.Integration?.IntegrationId
                });

                if (shipment.Method.TrackingNumber != null)
                {
                    fields.Add(new StringCustomFieldRef {
                        scriptId = "custbody_3k_nro_seguimiento",
                        value = shipment.Method.TrackingNumber
                    });

                    fields.Add(new StringCustomFieldRef {
                        scriptId = "custbody_3k_nro_guia_envio",
                        value = shipment.Method.TrackingNumber
                    });
                }
            }

            return fields.ToArray();
        }
        public string GetOrderLocation(IEnumerable<dynamic> items, SalesOrderRetrieveDTO salesOrder, NetSuiteApi api)
        {
            string salesOrderLocation = null;
            try
            {
                salesOrderLocation = items.First().preferredLocation.internalId;
            }
            catch
            {
                /* Is not an InventoryItem or it hasn't a preferred location */
                try
                {
                    salesOrderLocation = items.First().location.internalId;
                }
                catch
                {
                    /* Is not a KitItem item or it hasn't a preferred location */
                }
            }

            return salesOrderLocation ?? api.Locations.GetOrCreateLocation(salesOrder.Warehouse);
        }
        public void TransformOrder(SalesOrder netSuiteOrder, SalesOrderRetrieveDTO salesOrder, NetSuiteApi api)
        {
            netSuiteOrder.tranId = salesOrder.Id;

            netSuiteOrder.orderStatus = SalesOrderOrderStatus._pendingApproval;
            netSuiteOrder.orderStatusSpecified = true;

            netSuiteOrder.otherRefNum = salesOrder.GetMeliIntegrationId();

            netSuiteOrder.leadSource = new RecordRef
            {
                internalId = this.getLeadSourceId(api.Credentials.AccountName).ToString()
            };
        }
        private string GetSalesOrderAndCreatePayments(SalesOrderRetrieveDTO salesOrder)
        {
            var netSuiteOrder = this.getSalesOrder(salesOrder.Id);

            if (salesOrder.IsPaid)
                this.createPayments(salesOrder.Payments, netSuiteOrder);

            return netSuiteOrder.internalId;
        }
        /// <summary>
        /// Adapts the sales order to the NetSuite model.
        /// </summary>
        private SalesOrder generateSalesOrder(SalesOrderRetrieveDTO salesOrder)
        {
            var address = this.buildAddress(salesOrder.Contact) ?? this.api.Integration.GetDefaultAddress(this.api);

            var items = salesOrder.Lines.Select(it => this.api.Items.FindItemByUpcCode(it.Variation.Sku)); // TODO: Actualizar esto

            var lines = salesOrder.Lines.Select((it, i) =>
            {
                var netSuiteItem = items.ToArray()[i];

                var line = new SalesOrderItem {
                    quantity = it.Quantity, quantitySpecified = true,
                    rate = this.api.Integration.GetPriceOfLine(it, netSuiteItem, this.api).ToString(CultureInfo.InvariantCulture),
                    item = new RecordRef
                    {
                        internalId = netSuiteItem.internalId
                    },
                    price = new RecordRef {  internalId = "-1" }
                };

                this.api.Integration.TransformLine(line, it, this.api);
                return line;
            }).ToList();

            if (salesOrder.ShippingCost > 0)
                lines.Add(this.api.Integration.GetShipmentLineFor(salesOrder.ShippingCost, api));

            bool wasCreatedNow;
            var customer = this.getOrCreateCustomer(salesOrder.Contact, address, salesOrder.Lines.First(), out wasCreatedNow);

            var customerAddressbook = customer.addressbookList.addressbook.First(it => it.defaultBilling && it.defaultBillingSpecified);

            var netSuiteOrder = new SalesOrder
            {
                entity = new RecordRef { internalId = customer.internalId },

                itemList = new SalesOrderItemList
                {
                    item = lines.ToArray()
                },

                location = new RecordRef
                {
                    internalId = this.api.Integration.GetOrderLocation(items, salesOrder, this.api)
                },

                shippingAddress = salesOrder.IsForShip
                    ? this.buildAddress(salesOrder.Contact) : null,

                shippingCost = salesOrder.ShippingCost,
                shippingCostSpecified = salesOrder.IsForShip,

                billAddressList = new RecordRef { internalId = customerAddressbook.internalId, name = "addressBook" },

                trackingNumbers = String.Join(",", salesOrder.Shipments.Select(it => it.Method.TrackingNumber)),
                memo = salesOrder.Notes,

                externalId = salesOrder.Id,

                customFieldList = this.api.Integration.GetOrderFields(salesOrder, this.api)
            };

            this.api.Integration.TransformOrder(netSuiteOrder, salesOrder, this.api);
            return netSuiteOrder;
        }
 public string PostSalesOrder(SalesOrderRetrieveDTO salesOrder)
 {
     mutex.WaitOne();
     try {
         return this.netSuite.Orders.CreateOrUpdateSalesOrder(salesOrder);
     } finally { mutex.ReleaseMutex(); }
 }