SAGE API - Stock Transaction

Boa tarde,

Deparei-me com o seguinte problema ao utilizar a API Sage 50c.

Ao efetuar uma Stock Transacation (Fabricação) onde a saída contem um artigo cujo o preço unitário é 0.2€ e o peso 0.1Kg. o documento não é integrado.

O erro parece estar relacionado com arredondamentos da função " bsoStockTransaction.AddDetail(transDetail, true);".

Pois ao remover as linhas de código que vão buscar o preço de artigo ou alterando a quantidade de artigo para 1Kg.

A linha em questão:

 

 [
  {
    "TransSerial": null,
    "TransDocument": null,
    "TransDocNumber": 0,
    "Key": 1,
    "CreateDate": "2025-07-01T16:19:46.189",
    "CreateTime": "1899-12-30T00:00:00",
    "OriginCreateDate": "1899-12-30T00:00:00",
    "OriginTransSerial": null,
    "OriginTransDocument": null,
    "OriginTransDocNumber": 0,
    "OriginLineItemID": 0,
    "OriginLineItemSubID": 0,
    "OriginQuantity": 0,
    "OriginUnits": 0,
    "DestinationTransSerial": null,
    "DestinationTransDocument": null,
    "DestinationTransDocNumber": 0,
    "DestinationLineItemID": 0,
    "DestinationLineItemSubID": 0,
    "DestinationQuantity": 0,
    "DestinationUnits": 0,
    "TransactionConverted": false,
    "LineItemID": 1,
    "LineItemSubID": 0,
    "ItemID": "7025",
    "POSItemID": null,
    "BarCode": null,
    "Lot": {
      "ItemID": null,
      "EditionID": 0,
      "EffectiveDate": "1899-12-30T00:00:00",
      "ExpirationDate": "1899-12-30T00:00:00",
      "SalePrice": {
        "LotID": null,
        "PriceLineID": 0,
        "SizeID": 0,
        "ColorID": 0,
        "UnitOfMeasureID": null,
        "PropertyValue1": null,
        "PropertyValue2": null,
        "PropertyValue3": null,
        "UnitPrice": 0,
        "TaxIncludedPrice": 0,
        "CreateDate": "1899-12-30T00:00:00",
        "CurrencyID": "EUR",
        "CurrencyFactor": 1,
        "CurrencyExchange": 1,
        "FixedProfitRate": 0,
        "ExcludesGlobalDiscount": false,
        "DiscountPercent": 0,
        "PriceUnitID": null
      },
      "SaveSalePrice": false,
      "ReturnWeek": 0,
      "ReturnYear": 0,
      "ItemLotDescription": null,
      "SupplierItemID": null,
      "BarCode": null,
      "StoreID": 0,
      "LotID": null
    },
    "ItemType": 0,
    "SupplierItemID": null,
    "Color": {
      "ColorID": 0,
      "ColorKey": null,
      "Description": null,
      "ColorCode": 0,
      "ExtendedProperties": [],
      "PantoneCode": null
    },
    "Size": {
      "SizeID": 0,
      "SizeKey": null,
      "Description": null,
      "ExtendedProperties": [],
      "StandardSizeID": 0,
      "GenderID": 0,
      "ClothingTypeID": 0
    },
    "GridSize": [],
    "Description": "Sal",
    "ShortDescription": null,
    "TaxableGroupID": 3,
    "Taxes": [],
    "TaxList": [],
    "UnitOfSaleID": "KG",
    "AlternativeUnitOfStock": null,
    "WeightUnitOfMeasure": "UNI",
    "WeightMeasure": 0,
    "Graduation": 0,
    "ItemTax": 1,
    "ItemTax2": 1,
    "ItemTax3": 1,
    "PhysicalQtyRule": 3,
    "CountedQuantity": 0,
    "ConsignmentQuantity": 0,
    "Quantity1": 0,
    "Quantity2": 1,
    "Quantity3": 1,
    "Quantity4": 1,
    "ComponentQty": 0,
    "UnitCasesCount": 0,
    "DiscountPercent": 0,
    "DiscountValue": 0,
    "UnitDiscountValue": 0,
    "OriginalUnitPrice": 0,
    "OriginalTaxIncludedPrice": 0,
    "OriginalDiscountPercent": 0,
    "FamilyID": 36,
    "FamilyName": null,
    "FamilyMaximumDiscount": 0,
    "MandatoryCustomer": false,
    "WarehouseID": 14,
    "WarehouseOutgoing": 0,
    "WarehouseReceipt": 0,
    "CumulativeDiscountPercent1": 0,
    "CumulativeDiscountPercent2": 0,
    "CumulativeDiscountPercent3": 0,
    "PaymentDiscountPercent1": 0,
    "PaymentDiscountPercent2": 0,
    "PaymentDiscountPercent3": 0,
    "PartyTypeCode": -1,
    "PartyID": 0,
    "CustomerImputeID": 0,
    "ImputeToCustomerID": 0,
    "BillToPartyID": 0,
    "SalesmanId": 0,
    "TotalGrossAmount": 0.040000000000000001,
    "TotalLineItemDiscountAmount": 0,
    "TotalGlobalDiscountAmount": 0,
    "TotalNetAmount": 0.040000000000000001,
    "TotalNetBaseTaxAmount": 0.040000000000000001,
    "TotalNetPrintAmout": 0.040000000000000001,
    "TotalTaxAmount": 0,
    "TotalOtherTaxAmount": 0,
    "TotalAmount": 0.040000000000000001,
    "TotalTaxIncludedAmount": 0.040000000000000001,
    "ShareFreightAmount": 0,
    "BaseCurrency": {
      "CurrencyID": "EUR",
      "CurrencyKey": "",
      "Description": "EUROS",
      "SaleExchange": 1,
      "BuyExchange": 1,
      "ExchangeDate": "2002-01-01T00:00:00",
      "ItsEuroCurrency": false,
      "EuroConversionRate": 1,
      "RelatedCurrencyID": "EUR",
      "Symbol": "\u20AC",
      "SymbolPosition": "# 1",
      "NegativeFormat": "-#1",
      "decimalPlaces": 2,
      "PriceItemDecimalPlaces": 2,
      "FormatMask": "",
      "ISOCode": "EUR",
      "Inactive": false
    },
    "QntyReorderPoint": 0,
    "QntyAvailableBalanceCount": 0,
    "QntyPhysicalBalanceCount": 0,
    "QntyWrPhysicalBalanceCount": 0,
    "QntyWrAvailableBalanceCount": 0,
    "QntyPhysicalBalanceDiff": 0,
    "UnitsAvailableBalanceCount": 0,
    "UnitsPhysicalBalanceCount": 0,
    "UnitsWrPhysicalBalanceCount": 0,
    "UnitsWrAvailableBalanceCount": 0,
    "UnitsPhysicalBalanceDiff": 0,
    "AverageCostPrice": 0,
    "LastCostPrice": 0,
    "AverageCostStockValue": 0,
    "LastCostStockValue": 0,
    "DatePhysicalBalanceCount": "2025-07-01T16:19:46.189",
    "TimeAdjustmentBalanceCount": "1899-12-30T16:19:46.19",
    "FrequentShopperPoints": 0,
    "VoucherGiftValue": 0,
    "TransactionDetailClosed": false,
    "TempContractReferenceNumber": null,
    "ItemExtraInfo": {
      "FishDetails": {
        "ScientificName": null,
        "ProductionMethodID": 0,
        "ProductionMethodName": null,
        "CaptureAreaID": 0,
        "CaptureAreaDescription": null,
        "CaptureCountryID": null,
        "CaptureCountryName": null,
        "NetDrainedWeight": 0,
        "NetDrainedUnitOfMeasure": null,
        "SubCaptureAreaID": 0,
        "SubCaptureAreaDescription": null,
        "FishingGearID": null,
        "FishingGearDescription": null,
        "FishingGearCategory": null,
        "ConservationMethod": 0
      },
      "ReadQuantityFromScale": false,
      "CanotChangeSalePrice": false,
      "TagAlongItem": null,
      "TagAlongQuantity": 0,
      "InformationMessage": null,
      "StockManagement": true,
      "ItemAverageUnitPrice": 0,
      "ItemAverageTaxIncludedPrice": 0,
      "ItemLastCostUnitPrice": 0,
      "ItemLastCostTaxIncludedPrice": 0,
      "ItemQuantityCalcFormula": "",
      "DefaultQntMeasure1": 0,
      "DefaultQntMeasure2": 0,
      "DefaultQntMeasure3": 0,
      "NeededComponents": 0,
      "UseComponentPrices": false,
      "UseComponentPriceLineID": 0,
      "ItemVariables": null,
      "PrintStub": false,
      "DoNotGroup": false,
      "PictureName": null,
      "OriginalTaxableGroupID": 0
    },
    "ItemProperties": {
      "PropertyID1": "LOTE",
      "PropertyID2": null,
      "PropertyID3": null,
      "PropertyValue1": "245-24",
      "PropertyValue1_Key2": null,
      "PropertyValue1_Key3": null,
      "PropertyValue2": null,
      "PropertyValue2_Key2": null,
      "PropertyValue2_Key3": null,
      "PropertyValue3": null,
      "PropertyValue3_Key2": null,
      "PropertyValue3_Key3": null,
      "SupplierID": 0,
      "ProductionDate": "1899-12-30T00:00:00",
      "ExpirationDate": "1899-12-30T00:00:00",
      "PhysicalQty": 0,
      "PhysicalUnits": 0,
      "LastCostPrice": 0,
      "AverageCostStockValue": 0,
      "ControlType": 0,
      "ControlMode": 0,
      "UseExpirationDate": false,
      "UseProductionDate": false,
      "ExpirationDateControl": 0,
      "MaximumQuantity": 0,
      "UsePriceOnProp1": false,
      "UsePriceOnProp2": false,
      "UsePriceOnProp3": false,
      "DirectEntry": false,
      "HasPropertyValues": true,
      "HasPropertyIDs": true
    },
    "ItemContractGuid": null,
    "IsComponent": false,
    "Comments": null,
    "SecondHandTaxRegimen": false,
    "PriceAndDiscountChangeFlags": 0,
    "OfferTypeFlags": 0,
    "PromotionApplied": false,
    "PromotionAppliedQERO": false,
    "ProductCode": null,
    "PlantProtectionSaleAuthNumber": null,
    "ProductCategory": 1,
    "ExtendedProperties": [],
    "DiscountSettings": {
      "DiscountID": 0,
      "CanBeEvaluated": false,
      "UseTaxIncludedValues": false,
      "OfferSetting": null,
      "PriceSetting": null,
      "OfferBaseQuantity": 0
    },
    "Guid": "4443E45F79118747A6C7C4492701E368",
    "Quantity": 0.20000000000000001,
    "Units": 0.20000000000000001,
    "StockUnits": 0.20000000000000001,
    "UnitConversion": 1,
    "PackQuantity": 1,
    "QuantityFactor": 1,
    "PackUnitPrice": 0.22,
    "PackTaxIncludedPrice": 0.23319999999999999,
    "UnitList": [
      {
        "UnitOfMeasure": "KG",
        "UnitDescription": "KG",
        "UnitConversion": 1,
        "UnitType": 3
      }
    ],
    "HasComponents": false,
    "HasPropertiesOnComponents": false,
    "TaxIncludedPrice": 0.23319999999999999,
    "UnitPrice": 0.22,
    "ActualDeliveryDate": "2025-07-01T16:19:46.189",
    "PhysicalQtyDate": "2025-07-01T16:19:46.189",
    "RequiredDeliveryDateTime": "1899-12-30T00:00:00",
    "ComponentList": [],
    "Signature": null,
    "ExtraFieldList": [],
    "RetentionTax": 0,
    "AdvancementOriginItemID": null,
    "AdvancementMethod": 0,
    "AdvancementOriginDescription": null
  }
]

//Preço
transDetail.UnitPrice = Math.Round(item.SalePrice[0, 0, string.Empty, 0, item.UnitOfSaleID].UnitPrice,2);
transDetail.TaxIncludedPrice = Math.Round(item.SalePrice[0, 0, string.Empty, 0, item.UnitOfSaleID].TaxIncludedPrice,2);

O que é estranho que não ocorre nenhum erro de execução e no final da transação é retornado o numero de documento, mas no entanto o documento não é gravado na BD.

  internal void TransStockAddDetail(StockTransaction stockTrans, TransactionDetails transactionDetails, Transaction transaction)
  {
      try
      {
          BSOItemTransactionDetail BSOItemTransDetail = null;
          // Motor dos detalhes (linhas)
          BSOItemTransDetail = new BSOItemTransactionDetail();
          BSOItemTransDetail.TransactionType = stockTrans.TransDocType;
          // Utilizador e permissões
          BSOItemTransDetail.UserPermissions = systemSettings.User;
          BSOItemTransDetail.PermissionsType = FrontOfficePermissionEnum.foPermByUser;
          //
          bsoStockTransaction.BSOStockTransactionDetail = BSOItemTransDetail;
          BSOItemTransDetail = null;

          var transDetail = new ItemTransactionDetail();
          transDetail.BaseCurrency = stockTrans.BaseCurrency;
          transDetail.CreateDate = stockTrans.CreateDate;
          transDetail.ActualDeliveryDate = stockTrans.ActualDeliveryDate;
          transDetail.PartyTypeCode = stockTrans.PartyTypeCode;
          transDetail.PartyID = stockTrans.PartyID;
          transDetail.DatePhysicalBalanceCount = stockTrans.CreateDate;
          transDetail.TimeAdjustmentBalanceCount = stockTrans.CreateTime;
          transDetail.LineItemID = stockTrans.Details.Count + 1;

          //-----> INFORMAÇÕES DO PRODUTO
          var item = APIEngine.DSOCache.ItemProvider.GetItemForTransactionDetail(transactionDetails.ItemID, transDetail.BaseCurrency);

          //Idenitificação
          transDetail.ItemID = item.ItemID;
          transDetail.Description = item.Description;

          //Unidades
          transDetail.UnitList = item.UnitList.Clone();
          transDetail.SetUnitOfSaleID(transDetail.UnitOfSaleID);
          transDetail.UnitOfSaleID = item.GetDefaultUnitForTransaction(DocumentTypeEnum.dcTypeStock);
          transDetail.WeightUnitOfMeasure = item.WeightUnitOfMeasure;
          transDetail.WeightMeasure = item.WeightMeasure;

          transDetail.Quantity1 = 0;
          transDetail.Quantity2 = 1;
          transDetail.Quantity3 = 1;
          transDetail.Quantity4 = 1;

          //Qunatidade
          if (!string.IsNullOrEmpty(transDetail.ItemExtraInfo.ItemQuantityCalcFormula) && APIEngine.SystemSettings.SystemInfo.UseUnitWithFormulaItems)
          {
              transDetail.SetQuantity(StockHelper.CalculateQuantity(transDetail.ItemExtraInfo.ItemQuantityCalcFormula, transDetail, true));
          }
          else
          {
              transDetail.SetQuantity(StockHelper.CalculateQuantity(null, transDetail, true));
          }
          transDetail.SetQuantity(Math.Round(transactionDetails.Quantity,3));

          //Informação Adicional
          transDetail.FamilyID = item.Family.FamilyID;
          transDetail.ItemExtraInfo.ItemQuantityCalcFormula = item.ItemQuantityCalcFormula;

          //Preço
          transDetail.UnitPrice = Math.Round(item.SalePrice[0, 0, string.Empty, 0, item.UnitOfSaleID].UnitPrice,2);
          transDetail.TaxIncludedPrice = Math.Round(item.SalePrice[0, 0, string.Empty, 0, item.UnitOfSaleID].TaxIncludedPrice,2);

          //Armazem
          transDetail.WarehouseID = transactionDetails.WarehouseID;
          transDetail.PhysicalQtyRule = transactionDetails.stockQtyRule;

          //Taxas
          transDetail.TaxableGroupID = item.TaxableGroupID;
          transDetail.Graduation = item.Graduation;
          transDetail.ItemTax = item.ItemTax;
          transDetail.ItemTax2 = item.ItemTax2;
          transDetail.ItemTax3 = item.ItemTax3;

          //Alterar a categoria em caso de necessidade
          if (item.ProductCategory == 0 && item != null)
              transDetail.ProductCategory = ProductCategoryEnum.pcMerchandise;
          else
              transDetail.ProductCategory = item.ProductCategory;

          //*** PROPERTIES -- Uncomment to use
          if (item.PropertyID1.Equals("LOTE", StringComparison.CurrentCultureIgnoreCase))
          {
              transDetail.ItemProperties.ResetValues();

              transDetail.ItemProperties.PropertyID1 = item.PropertyID1;
              transDetail.ItemProperties.ControlType = item.PropertyControlType;
              transDetail.ItemProperties.ControlMode = item.PropertyControlMode;
              transDetail.ItemProperties.UseExpirationDate = item.PropertyUseExpirationDate;
              transDetail.ItemProperties.UseProductionDate = item.PropertyUseProductionDate;
              transDetail.ItemProperties.ExpirationDateControl = item.PropertyExpirationDateControl;
              transDetail.ItemProperties.MaximumQuantity = item.PropertyMaximumQuantity;
              //
              transDetail.ItemProperties.PropertyValue1 = transactionDetails.Lote;
              if (transactionDetails.stockQtyRule == StockQtyRuleEnum.stkQtyReceipt)
              {
                  transDetail.ItemProperties.ProductionDate = transaction.dtProducao;
                  transDetail.ItemProperties.ExpirationDate = transactionDetails.dtValidity;
              }
          }

          bsoStockTransaction.AddDetail(transDetail, true);
          item = null;
      }
      catch (Exception ex)
      {
          LOG.SaveLog("ERRO ", ex.Message);
          throw new Exception(ex.Message);
      }
  }

Se alguém tiver alguma sugestão, agradeço.

Obrigado.