Insert Data SAP B1 with C# - c#

I'm trying to input purchase order data with the DI API in C #. after I run the script, the connection is successful and the input data is successful but when I check SAP the input data is not there.
this is the script I used:
try
{
SAPbobsCOM.Documents PO = null;
PO = ocompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oPurchaseOrders);
PO.CardCode = "VT0970";
PO.CardName = "FELICOM";
PO.Series = int.Parse("16N");
PO.DocNum = 211000002;
PO.DocDate = DateTime.Parse("15.10.19");
PO.DocDueDate = DateTime.Parse("18.10.19");
PO.TaxDate = DateTime.Parse("15.10.19");
PO.Lines.ItemCode = "TH-NONSTOK";
PO.Lines.ItemDescription = "Mouse Rexus G-6";
PO.Lines.Quantity = 2;
PO.Lines.Price = 150000;
PO.DiscountPercent = 0;
PO.Lines.VatGroup = "IPPN0";
PO.Lines.AccountCode = "6020-1500";
PO.Lines.Add();
int res = PO.Add();
if (res == 0)
{
MessageBox.Show("Add Purchase Order successfull");
}
else
{
MessageBox.Show(ocompany.GetLastErrorDescription()); //#scope_identity
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Is there something wrong with my script?
Please help.

after "Add Purchase Order successfull" should be commit work
if (ocompan.InTransaction)
ocompan.EndTransaction(SAPbobsCOM.BoWfTransOpt.wf_Commit);
else
throw new Exception("ERROR: Transaction closed before EndTransaction!!!");

Related

Unable to get a table data from SAP

This is a c# method that invokes SAP BAPI.
public Message ReleaseBapi(string orderNumber)
{
Message msg = new Message();
DataTable dt = new DataTable();
_ecc = ERPRfcDestination.InitialiseDestination();
try
{
IRfcFunction api = _ecc.Repository.CreateFunction("BAPI_PRODORD_RELEASE");
IRfcTable orderNumTable = api.GetTable("ORDERS");
orderNumTable.Insert();
IRfcStructure ItemData = orderNumTable.CurrentRow;
orderNumber = orderNumber.PadLeft(12,'0');
ItemData.SetValue("ORDER_NUMBER", orderNumber);
api.SetValue("ORDERS", orderNumTable);
BeginContext();
api.Invoke(_ecc);
//EndContext();
IRfcTable detReturnTable = api.GetTable("DETAIL_RETURN");//On this line I am getting RfcInvalidStateException
IRFCToDatatable convertToDT = new IRFCToDatatable();
dt = convertToDT.ToDataTable(detReturnTable, dt);
if (dt.Rows.Count > 0)
{
msg.Msg = "Order number " + orderNumber + " released";
msg.MsgType = "S";
}
else { RollbackAPI(); }
}
catch (Exception ex)
{
msg.MsgType = "D";
msg.Msg = ex.Message;
RollbackAPI();
}
finally
{
EndContext();
}
return msg;
}
I checked every other instances where similar line of code is written and on debugging I found that it works as expected. Above is the only place where I am getting this error although I was able to invoke the Rfc method.

How to transfer payment line into Sage 50?

I'm using sagecrmErp2008feeds to the integration with my application. I'm able to create SalesCredit and SalesInvoice data. But I would like to transfer payment data from my application to Sage50.
Which feed Entry should I use for that for payment transfer ? Please see my Invoice code example. I would like to use the same way to transfer payment but I'm not getting feedentry for that. Here I'm using salesInvoiceFeedEntry feed entry.
public IResult<string> CreateSalesInvoice(Sage50Transaction data)
{
var result = new Result<string>();
try
{
var tradingAccount = GetCustomer(data.CustomerGuid);
if (tradingAccount == null)
{
throw new Exception("Customer not found in Sage");
}
var salesInvoice = new salesInvoiceFeedEntry
{
tradingAccount = tradingAccount
};
salesInvoice.reference = data.ReferenceId;
salesInvoice.reference2 = data.OurRef;
salesInvoice.customerReference = data.YourRef;
salesInvoice.netTotal = data.NetSub;
salesInvoice.taxDate = data.TransactionDate;
salesInvoice.date = data.TransactionDate;
salesInvoice.salesInvoiceLines = new salesInvoiceLineFeed();
if (data.Lines != null)
{
foreach (var item in data.Lines)
{
salesInvoice.salesInvoiceLines.Entries.Add(GetInvoiceLineItem(item));
}
}
var invoiceRequest = new SDataRequest(uri.Uri, salesInvoice, Sage.Integration.Messaging.Model.RequestVerb.POST);
invoiceRequest.Username = Username;
invoiceRequest.Password = Password;
salesInvoiceFeedEntry savedSalesInvoice = new salesInvoiceFeedEntry();
invoiceRequest.RequestFeedEntry<salesInvoiceFeedEntry>(savedSalesInvoice);
result.Data = savedSalesInvoice.UUID.ToString();
result.HasData = !string.IsNullOrEmpty(result.Data);
}
catch (Exception ex)
{
result.HasData = false;
result.Data = null;
result.Error = ex;
result.FailMessage = ex.Message;
}
return result;
}
As per my understanding, "payment transfer" is not possible from 3rd party to sage50, as the Sage 50 Accounts does not support this.

Validating digitaly signed PDF Spire.Pdf C#

So I am developing a web app that generates a PDF contract from a partial view, and then validates the digital signiture. I came accross an example here . The problem is that an exception is thrown when validating the signiture and for the life of me I cant figure out why...
Here is the code :
public async Task<ActionResult> Upload(HttpPostedFileBase FileUpload)
{
ActionResult retVal = View();
AspNetUser user = DbCtx.AspNetUsers.Find(User.Identity.GetUserId());
bool signitureIsValid = false;
string blobUrl = string.Empty;
if (FileUpload != null && FileUpload.ContentLength > 0)
{
string fileName = Guid.NewGuid().ToString() + RemoveAllSpaces(FileUpload.FileName);
string filePath = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/Content/pdfs"), fileName);
FileUpload.SaveAs(filePath);
List<PdfSignature> signatures = new List<PdfSignature>();
using (var doc = new PdfDocument(filePath))
{
var form = (PdfFormWidget) doc.Form;
int count = 0;
try
{
count = form.FieldsWidget.Count;
}
catch
{
count = 0;
}
for (int i = 0; i < count; ++i)
{
var field = form.FieldsWidget[i] as PdfSignatureFieldWidget;
if (field != null && field.Signature != null)
{
PdfSignature signature = field.Signature;
signatures.Add(signature);
}
}
}
PdfSignature signatureOne = signatures[0];
try
{
signitureIsValid = signatureOne.VerifySignature(); // HERE SHE BLOWS !
if (signitureIsValid)
{
blobPactUrl = await BlobUtil.BasicStorageBlockBlobOperationsAsync(System.IO.File.ReadAllBytes(filePath));
if (!string.IsNullOrEmpty(blobPactUrl))
{
ApplicantInfo info = DbCtx.ApplicantInfoes.FirstOrDefault(x => x.UserId == user.Id);
info.URL = blobUrl;
info.SignatureIsValid = true;
info.ActivationDate = DateTime.Now;
info.ActiveUntill = DateTime.Now.AddYears(1);
DbCtx.Entry(info).State = System.Data.Entity.EntityState.Modified;
DbCtx.SaveChanges();
retVal = RedirectToAction("Publications");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
System.IO.File.Delete(filePath);
}
}
return retVal;
}
Here is an image of
what it looks like when I'm debuging:
I have checked the signiture and it is valid and cerified... I know I'm missing something basic here... Please help me internet!
Just noticed that I posted this. . . Turns out that the problem was due to bug in the package itself. Upon asking the lovely people at E-Iceblue, the bug was recreated, solved and a new version of Spire.PDF was up on nuget within a week.
great job E-Iceblue, it worked fine :)

Connect to a Webservice - convert C# to PHP code

I have a sample code I got from a documentation provided by a merchant. I think the code is in C#. I need to write a code for PHP but I don't have any idea about C# so I'm having a problem with this. I've tried to write a PHP code for this but it doesn't seem right.
By the way, this is a webservice kind of setup and it uses WCF to expose various endpoints. Here's the endpoint they've provided to me: http://services.scorpion.biz/Public/Leads/ExternalLead.svc
Here's the C# code:
public bool SubmitLead(string contactName, string contactNumber) {
bool outcome = false;
string message = string.Empty;
if (contactNumber.Length <= 9) {
message = "Telephone number is too short";
outcome = false;
} else if (contactNumber.Length > 11) {
message = "Telephone number is too long";
outcome = false;
} else if (contactNumber.Length == 10 && contactNumber[0] != '0') {
message = "Telephone must start with a ZERO";
outcome = false;
} else if (contactNumber.Length == 11 && contactNumber.Substring(0, 2) != "27") {
message = "Telephone must start with a 27";
outcome = false;
} else {
WSExternalLead.LeadRequestMessage request = new
WSExternalLead.LeadRequestMessage();
request.Message = “Your Keyword” + ". Contact Name: " + contactName + ".
Contact Number: " + contactNumber;
request.TelephoneNumber = contactNumber;
request.Network = “IMU”;
request.ReceivedTime = DateTime.Now;
using (WSExternalLead.ExternalLeadClient client = new WSExternalLead.ExternalLeadClient()) {
try {
WSExternalLead.LeadResponseMessage response = null;
response = client.GenerateLead(request);
if (response.Result != true) {
message = "We were unable to process your request at this
time. Error: " + response.ErrorMessage;
outcome = false;
} else {
message = "Thank you for your interest in Scorpion Legal
Protection. We will get back to you shortly.";
outcome = true;
}
} catch (FaultException fx) {
message = "We were unable to process your request at this time.
Fault: " + fx.Message;
outcome = false;
} catch (Exception ex) {
message = "We were unable to process your request at this time.
Exception: " + ex.Message;
outcome = false;
}
}
}
HttpContext.Current.Session["OUTCOME"] = outcome;
HttpContext.Current.Session["MESSAGE"] = message;
return outcome;
}
Here's the PHP code that I've written:
// Read values to variables
$username = $_GET['un'];
$usersurname = $_GET['ul'];
$phonesubmit= $_GET['up'];
$useremail = $_GET['ue'];
$aff_id = $_GET['aff'];
$unique_id = $_GET['uid'];
$rdate = date('m/d/Y G:i:s');
$rdate = date("c", strtotime($rdate));
$wsdlFile = "http://services.scorpion.biz/Public/Leads/ExternalLead.svc?WSDL";
$client = new SoapClient($wsdlFile);
$variables->TelephoneNumber = $phonesubmit;
$variables->Message = "IMU. Name: $username $usersurname. Contact Number: $phonesubmit";
$variables->Network = "IMU";
$variables->ReceivedTime = $rdate;
$result = $client->GenerateLead($variables);
$returnMessage = $result->Result;
$returnMessage = trim($returnMessage);
if ($returnMessage == ""){
$returnMessage = $result->ErrorMessage;
}
Any idea on how to solve this would be greatly appreciated. Thanks.

SQLite connection strategies

I have a database that may be on the network drive.
There are two things that I want to achieve:
When the first user connects to it in read-only mode (he doesn't
have a read-write access to the location, or the database is
read-only), other users must use the read-only connection also (even
if they have RW access).
When the first user connects to it in RW mode, others can not
connect to the database at all.
I'm using SQLite, and the concurrency should not be the problem, as the database should never be used by more than 10 people at the same time.
UPDATE: This is a sample that I'm trying to make work, so I could implement it in the program itself. Almost everything can be changed.
UPDATE: Now when I finally understood what #CL. was telling me, I made it work and this is the updated code.
using System.Diagnostics;
using System.Linq;
using System.IO;
using DbSample.Domain;
using DbSample.Infrastructure;
using NHibernate.Linq;
using NHibernate.Util;
namespace DbSample.Console
{
class Program
{
static void Main(string[] args)
{
IDatabaseContext databaseContext = null;
databaseContext = new SqliteDatabaseContext(args[1]);
var connection = LockDB(args[1]);
if (connection == null) return;
var sessionFactory = databaseContext.CreateSessionFactory();
if (sessionFactory != null)
{
int insertCount = 0;
while (true)
{
try
{
using (var session = sessionFactory.OpenSession(connection))
{
string result;
session.FlushMode = NHibernate.FlushMode.Never;
var command = session.Connection.CreateCommand();
command.CommandText = "PRAGMA locking_mode=EXCLUSIVE";
command.ExecuteNonQuery();
using (var transaction = session.BeginTransaction(ReadCommited))
{
bool update = false;
bool delete = false;
bool read = false;
bool readall = false;
int op = 0;
System.Console.Write("\nMenu of the day:\n1: update\n2: delete\n3: read\n4: read all\n0: EXIT\n\nYour choice: ");
op = System.Convert.ToInt32(System.Console.ReadLine());
if (op == 1)
update = true;
else if (op == 2)
delete = true;
else if (op == 3)
read = true;
else if (op == 4)
readall = true;
else if (op == 0)
break;
else System.Console.WriteLine("Are you retarded? Can't you read?");
if (delete)
{
System.Console.Write("Enter the ID of the object to delete: ");
var objectToRemove = session.Get<MyObject>(System.Convert.ToInt32(System.Console.ReadLine()));
if (!(objectToRemove == null))
{
session.Delete(objectToRemove);
System.Console.WriteLine("Deleted {0}, ID: {1}", objectToRemove.MyName, objectToRemove.Id);
deleteCount++;
}
else
System.Console.WriteLine("\nObject not present in the database!\n");
}
else if (update)
{
System.Console.Write("How many objects to add/update? ");
int number = System.Convert.ToInt32(System.Console.ReadLine());
number += insertCount;
for (; insertCount < number; insertCount++)
{
var myObject = session.Get<MyObject>(insertCount + 1);
if (myObject == null)
{
myObject = new MyObject
{
MtName = "Object" + insertCount,
IdLegacy = 0,
};
session.Save(myObject);
System.Console.WriteLine("Added {0}, ID: {1}", myObject.MyName, myObject.Id);
}
else
{
session.Update(myObject);
System.Console.WriteLine("Updated {0}, ID: {1}", myObject.MyName, myObject.Id);
}
}
}
else if (read)
{
System.Console.Write("Enter the ID of the object to read: ");
var objectToRead = session.Get<MyObject>(System.Convert.ToInt32(System.Console.ReadLine()));
if (!(objectToRead == null))
System.Console.WriteLine("Got {0}, ID: {1}", objectToRead.MyName, objectToRead.Id);
else
System.Console.WriteLine("\nObject not present in the database!\n");
}
else if (readall)
{
System.Console.Write("How many objects to read? ");
int number = System.Convert.ToInt32(System.Console.ReadLine());
for (int i = 0; i < number; i++)
{
var objectToRead = session.Get<MyObject>(i + 1);
if (!(objectToRead == null))
System.Console.WriteLine("Got {0}, ID: {1}", objectToRead.MyName, objectToRead.Id);
else
System.Console.WriteLine("\nObject not present in the database! ID: {0}\n", i + 1);
}
}
update = false;
delete = false;
read = false;
readall = false;
transaction.Commit();
}
}
}
catch (System.Exception e)
{
throw e;
}
}
sessionFactory.Close();
}
}
private static SQLiteConnection LockDbNew(string database)
{
var fi = new FileInfo(database);
if (!fi.Exists)
return null;
var builder = new SQLiteConnectionStringBuilder { DefaultTimeout = 1, DataSource = fi.FullName, Version = 3 };
var connectionStr = builder.ToString();
var connection = new SQLiteConnection(connectionStr) { DefaultTimeout = 1 };
var cmd = new SQLiteCommand(connection);
connection.Open();
// try to get an exclusive lock on the database
try
{
cmd.CommandText = "PRAGMA locking_mode = EXCLUSIVE; BEGIN EXCLUSIVE; COMMIT;";
cmd.ExecuteNonQuery();
}
// if we can't get the exclusive lock, it could mean 3 things
// 1: someone else has locked the database
// 2: we don't have a write acces to the database location
// 3: database itself is a read-only file
// So, we try to connect as read-only
catch (Exception)
{
// we try to set the SHARED lock
try
{
// first we clear the locks
cmd.CommandText = "PRAGMA locking_mode = NORMAL";
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT COUNT(*) FROM MyObject";
cmd.ExecuteNonQuery();
// then set the SHARED lock on the database
cmd.CommandText = "PRAGMA locking_mode = EXCLUSIVE";
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT COUNT(*) FROM MyObject";
cmd.ExecuteNonQuery();
readOnly = true;
}
catch (Exception)
{
// if we can't set EXCLUSIVE nor SHARED lock, someone else has opened the DB in read-write mode and we can't connect at all
connection.Close();
return null;
}
}
return connection;
}
}
}
Set PRAGMA locking_mode=EXCLUSIVE to prevent SQLite from releasing its locks after a transaction ends.
I don't know if it can be done within db but in application;
You can set a global variable (not sure if it's a web or desktop app) to check if anyone connected and he has a write access or not.
After that you can check the other client's state.

Categories