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.
