Page 1 of 2

Shipment import from CSV or Excel

PostPosted: Tue Jun 03, 2025 6:20 pm
by DannyC
I'm writing a plugin to populate a shipment form from Excel/CSV.

In the Excel sheet is a column for PO_OrderNo, InvoiceNo, PartNo, Qty

I've managed to populate the Purchase Order grid, the Invoices grid but I am having trouble populating the shipment lines grid.
I am using
Code: Select all
JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line shipmentLine = shipment.Manager.CollectionItemFactory.CreateCollectionItem<JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line>();

to instantiate the shipment line and then using
Code: Select all
shipmentLine.PurchaseOrderLine.ReadRecord

to read the purchase order line from the PO from the OrderNo and PartNo. Then use
Code: Select all
shipment.Lines.Add(shipmentLine);

But all that does is add basically a blank line with nothing populated except the PO line number.

Is there a way to have the shipment line pre-fill much of the grid with the data pulled in from the purchase order line? Or do I need to set each shipmentLine property? (like PartNo, description, FX rate, Unit cost, FX Unit cost, et al and so on and etc)
Or maybe that is not the correct object to instantiate? Maybe it should be
Code: Select all
JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.PurchaseOrderLine item = shipment.Manager.CollectionItemFactory.CreateCollectionItem<JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.PurchaseOrderLine>();

but I can't find a Read function to populate it.

Re: Shipment import from CSV or Excel

PostPosted: Wed Jun 04, 2025 6:52 pm
by SBarnes
As near as I can tell in having a quick look at it JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.PurchaseOrderLine has a method called AddToShipmentLines which is below, hopefully that helps



Code: Select all
 public void AddToShipmentLines()
        {
            IEnumerator enumerator = null;
            IEnumerator enumerator1 = null;
            ImportCost current;
            Line line = this.Manager.CollectionItemFactory.CreateCollectionItem<Line>();
            Line partNo = line;
            partNo.PurchaseOrderLine.ReadRecord(this.RecID);
            if (this.IN_SupplierWarehouse_RecID != null && this.IN_SupplierWarehouse_RecID.Trim().Length > 0)
            {
                partNo.SupplierWarehouse.ReadRecord(this.IN_SupplierWarehouse_RecID);
            }
            if (this.IN_Creditor_RecID != null && this.IN_Creditor_RecID.Trim().Length > 0)
            {
                partNo.Supplier.ReadRecord(this.IN_Creditor_RecID);
            }
            if (partNo.Supplier != null && partNo.Supplier.CreditorID != null && partNo.Supplier.CreditorID.Trim().Length > 0)
            {
                partNo.Creditor.ReadRecord(partNo.Supplier.CreditorID);
            }
            else if (line.IsNonInventory)
            {
                partNo.Creditor.ReadRecord(this.PurchaseOrderLines.PurchaseOrder.PurchaseOrder.Creditor.CreditorID);
            }
            if (this.IN_Main_RecID != null && this.IN_Main_RecID.Trim().Length > 0)
            {
                partNo.Inventory.ReadRecord(this.IN_Main_RecID);
            }
            partNo.Inventory.PartNo = this.PartNo;
            partNo.Inventory.Description = this.Description;
            if (this.PO_Classification_RecID != null && this.PO_Classification_RecID.Trim().Length > 0)
            {
                partNo.PurchaseOrderClassification.ReadRecord(this.PO_Classification_RecID);
            }
            partNo.QuantityOrdered = this.QuantityOrdered;
            if (decimal.Compare(partNo.QuantityOrdered, partNo.PurchaseOrderLine.QuantityDelivered) <= 0)
            {
                partNo.QuantityThisShipment = decimal.Zero;
            }
            else
            {
                partNo.QuantityThisShipment = decimal.Subtract(partNo.QuantityOrdered, partNo.PurchaseOrderLine.QuantityDelivered);
            }
            partNo.OrderedCost = this.OrderedCost;
            partNo.FXOrderedCost = this.SuppliersCost;
            partNo.UnitCostExTax = this.OrderedCost;
            partNo.FXRate = this.Lines.PurchaseOrder.PurchaseOrder.Creditor.CurrentFXRate;
            partNo.FXUnitCostExTax = this.SuppliersCost;
            if (this._TX_Main_RecID != null && this._TX_Main_RecID.Trim().Length > 0)
            {
                partNo.TaxRate.Read(this._TX_Main_RecID);
            }
            partNo.TaxAmount = this._TaxAmount;
            partNo.UnitCostIncTax = this.IncPrice;
            partNo.LineTotalExTax = this._LineTotalExTax;
            partNo.LineTotalIncTax = this._LineTotalIncTax;
            partNo.FXLineTotalExTax = this._FXTotal;
            partNo.OriginalUnitCostExTax = partNo.UnitCostExTax;
            partNo.OriginalLandedCost = decimal.Zero;
            partNo.OriginalSumOfApportionedCosts = decimal.Zero;
            partNo.PurchaseOrdersKey = this.PurchaseOrderLines.PurchaseOrder.RecID;
            partNo.InvoicesKey = "";
            partNo.ChangeSourceIsFromPurchaseOrderLine = true;
            partNo.UnitChanged = this.UnitChanged;
            partNo.FXChanged = this.FXChanged;
            partNo.ExChanged = this.ExChanged;
            partNo.TaxRateChanged = this.TaxRateChanged;
            partNo = null;
            this.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.Lines.Add(line);
            line.CalculateLandedCostTotal(line.UnitChanged);
            try
            {
                enumerator = this.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.Invoices.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    Invoice invoice = (Invoice)enumerator.Current;
                    if (!(Operators.CompareString(invoice.Creditor.CreditorID, this.PurchaseOrderLines.PurchaseOrder.PurchaseOrder.Creditor.CreditorID, false) == 0 & !invoice.Invoiced))
                    {
                        continue;
                    }
                    line.SetInvoicesKey(invoice.RecID);
                    invoice.DoLineCalculations();
                    try
                    {
                        enumerator1 = this.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.ImportCosts.GetEnumerator();
                        while (enumerator1.MoveNext())
                        {
                            current = (ImportCost)enumerator1.Current;
                            if (current.Apportioned)
                            {
                                continue;
                            }
                            current.AddShipmentLineToApportion(line);
                        }
                    }
                    finally
                    {
                        if (enumerator1 is IDisposable)
                        {
                            (enumerator1 as IDisposable).Dispose();
                        }
                    }
                    return;
                }
            }
            finally
            {
                if (enumerator is IDisposable)
                {
                    (enumerator as IDisposable).Dispose();
                }
            }
            try
            {
                enumerator1 = this.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.ImportCosts.GetEnumerator();
                while (enumerator1.MoveNext())
                {
                    current = (ImportCost)enumerator1.Current;
                    if (current.Apportioned)
                    {
                        continue;
                    }
                    current.AddShipmentLineToApportion(line);
                }
            }
            finally
            {
                if (enumerator1 is IDisposable)
                {
                    (enumerator1 as IDisposable).Dispose();
                }
            }
        }

Re: Shipment import from CSV or Excel

PostPosted: Thu Jun 05, 2025 4:03 pm
by DannyC
Thx Stuart,
That tells me I am on the right track. I just need to populate each property in the line.

All good, I can do that :D

EDIT: OK. I've gotten as far as I can using some of that code Stuart posted.
I've got some questions about the AddToShipmentLines() method.

1. ON the 4th & 5th lines is the following:
Code: Select all
JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line line = this.Manager.CollectionItemFactory.CreateCollectionItem<Line>();
JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line partNo = line;

Why are there 2 lines getting instantiated when both lines are the exact same type?

2. Why is partNo the one getting all the values set, and not line?

3. Several properties of JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line are read only, yet they're getting set in this code block. I've tried setting them & getting an error that they're read only.
These are the properties. (might be others too)
Code: Select all
TaxAmount
QuantityOrdered
OriginalUnitCostExTax
OriginalLandedCost
OriginalSumOfApportionedCosts


4. Before anything happens with partNo, it gets set to null with this line
Code: Select all
partNo = null

Why would it get set to null when there seems to be no assignment to anything using partNo? All that effort in the preceding lines for seemingly nothing?

Re: Shipment import from CSV or Excel

PostPosted: Fri Jun 13, 2025 10:52 am
by DannyC
Just a gentle bump. Keen to get some answers to those questions.

Re: Shipment import from CSV or Excel

PostPosted: Sat Jun 14, 2025 8:46 am
by SBarnes
DannyC wrote:1. ON the 4th & 5th lines is the following:
Code: Select all
JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line line = this.Manager.CollectionItemFactory.CreateCollectionItem<Line>();
JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line partNo = line;

Why are there 2 lines getting instantiated when both lines are the exact same type?


The code I gave you is decompiled code, the original code is visual basic and uses a with statement after the object is instantiated as line so that is how the decompiler is interpreting it.

DannyC wrote:2. Why is partNo the one getting all the values set, and not line?


Classes in c# are reference types so once partno is set to line basically they are pointing to the same block of memory and are the same object.

DannyC wrote:3. Several properties of JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line are read only, yet they're getting set in this code block. I've tried setting them & getting an error that they're read only.
These are the properties. (might be others too)
Code: Select all
TaxAmount
QuantityOrdered
OriginalUnitCostExTax
OriginalLandedCost
OriginalSumOfApportionedCosts



The following C# code from ChatGTP will set a read only property on an object using refelection, I didn't test that it will work but it should given my understanding of reflection, you may need to tweek the backing filed name as in Jiwa they are usually _ property name or m_property name

Code: Select all
using System;
using System.Reflection;

public static class ReflectionHelper
{
    public static bool SetReadOnlyPropertyValue(object target, string propertyName, object newValue)
    {
        if (target == null)
            throw new ArgumentNullException(nameof(target));
        if (propertyName == null)
            throw new ArgumentNullException(nameof(propertyName));

        Type type = target.GetType();
        PropertyInfo prop = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

        if (prop == null)
            throw new ArgumentException($"Property '{propertyName}' not found on type '{type.FullName}'.");

        // Try to get the backing field, typically named like "<PropertyName>k__BackingField"
        FieldInfo backingField = type.GetField($"<{propertyName}>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);

        if (backingField == null)
        {
            Console.WriteLine($"Backing field for property '{propertyName}' not found.");
            return false;
        }

        backingField.SetValue(target, newValue);
        return true;
    }
}



DannyC wrote:4. Before anything happens with partNo, it gets set to null with this line
Code: Select all
partNo = null

Why would it get set to null when there seems to be no assignment to anything using partNo? All that effort in the preceding lines for seemingly nothing?


C# likes to have things iniated to avoid certain issues that why the decompiler does it.

Re: Shipment import from CSV or Excel

PostPosted: Tue Jun 17, 2025 4:11 pm
by DannyC
The code I gave you is decompiled code, the original code is visual basic and uses a with statement after the object is instantiated as line

Hmmm, I'm not so sure.
Here is the same code block in VB. Can't see any with statement.
Code: Select all
        Public Sub AddToShipmentLines()
            Dim enumerator As IEnumerator = Nothing
            Dim enumerator1 As IEnumerator = Nothing
            Dim current As ImportCost
            Dim line As JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line = Me.Manager.CollectionItemFactory.CreateCollectionItem(Of JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line)()
            Dim partNo As JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line = line
            partNo.PurchaseOrderLine.ReadRecord(Me.RecID)
            If (Me.IN_SupplierWarehouse_RecID IsNot Nothing AndAlso Me.IN_SupplierWarehouse_RecID.Trim().Length > 0) Then
                partNo.SupplierWarehouse.ReadRecord(Me.IN_SupplierWarehouse_RecID)
            End If
            If (Me.IN_Creditor_RecID IsNot Nothing AndAlso Me.IN_Creditor_RecID.Trim().Length > 0) Then
                partNo.Supplier.ReadRecord(Me.IN_Creditor_RecID)
            End If
            If (partNo.Supplier IsNot Nothing AndAlso partNo.Supplier.CreditorID IsNot Nothing AndAlso partNo.Supplier.CreditorID.Trim().Length > 0) Then
                partNo.Creditor.ReadRecord(partNo.Supplier.CreditorID)
            ElseIf (line.IsNonInventory) Then
                partNo.Creditor.ReadRecord(Me.PurchaseOrderLines.PurchaseOrder.PurchaseOrder.Creditor.CreditorID)
            End If
            If (Me.IN_Main_RecID IsNot Nothing AndAlso Me.IN_Main_RecID.Trim().Length > 0) Then
                partNo.Inventory.ReadRecord(Me.IN_Main_RecID)
            End If
            partNo.Inventory.PartNo = Me.PartNo
            partNo.Inventory.Description = Me.Description
            If (Me.PO_Classification_RecID IsNot Nothing AndAlso Me.PO_Classification_RecID.Trim().Length > 0) Then
                partNo.PurchaseOrderClassification.ReadRecord(Me.PO_Classification_RecID)
            End If
            partNo.QuantityOrdered = Me.QuantityOrdered
            If (Decimal.Compare(partNo.QuantityOrdered, partNo.PurchaseOrderLine.QuantityDelivered) <= 0) Then
                partNo.QuantityThisShipment = Decimal.Zero
            Else
                partNo.QuantityThisShipment = Decimal.Subtract(partNo.QuantityOrdered, partNo.PurchaseOrderLine.QuantityDelivered)
            End If
            partNo.OrderedCost = Me.OrderedCost
            partNo.FXOrderedCost = Me.SuppliersCost
            partNo.UnitCostExTax = Me.OrderedCost
            partNo.FXRate = Me.Lines.PurchaseOrder.PurchaseOrder.Creditor.CurrentFXRate
            partNo.FXUnitCostExTax = Me.SuppliersCost
            If (Me._TX_Main_RecID IsNot Nothing AndAlso Me._TX_Main_RecID.Trim().Length > 0) Then
                partNo.TaxRate.Read(Me._TX_Main_RecID)
            End If
            partNo.TaxAmount = Me._TaxAmount
            partNo.UnitCostIncTax = Me.IncPrice
            partNo.LineTotalExTax = Me._LineTotalExTax
            partNo.LineTotalIncTax = Me._LineTotalIncTax
            partNo.FXLineTotalExTax = Me._FXTotal
            partNo.OriginalUnitCostExTax = partNo.UnitCostExTax
            partNo.OriginalLandedCost = Decimal.Zero
            partNo.OriginalSumOfApportionedCosts = Decimal.Zero
            partNo.PurchaseOrdersKey = Me.PurchaseOrderLines.PurchaseOrder.RecID
            partNo.InvoicesKey = ""
            partNo.ChangeSourceIsFromPurchaseOrderLine = True
            partNo.UnitChanged = Me.UnitChanged
            partNo.FXChanged = Me.FXChanged
            partNo.ExChanged = Me.ExChanged
            partNo.TaxRateChanged = Me.TaxRateChanged
            partNo = Nothing
            Me.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.Lines.Add(line)
            line.CalculateLandedCostTotal(line.UnitChanged)
            Try
                enumerator = Me.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.Invoices.GetEnumerator()
                While enumerator.MoveNext()
                    Dim invoice As JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Invoice = DirectCast(enumerator.Current, JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Invoice)
                    If (Not (Operators.CompareString(invoice.Creditor.CreditorID, Me.PurchaseOrderLines.PurchaseOrder.PurchaseOrder.Creditor.CreditorID, False) = 0 And Not invoice.Invoiced)) Then
                        Continue While
                    End If
                    line.SetInvoicesKey(invoice.RecID)
                    invoice.DoLineCalculations()
                    Try
                        enumerator1 = Me.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.ImportCosts.GetEnumerator()
                        While enumerator1.MoveNext()
                            current = DirectCast(enumerator1.Current, ImportCost)
                            If (current.Apportioned) Then
                                Continue While
                            End If
                            current.AddShipmentLineToApportion(line)
                        End While
                    Finally
                        If (TypeOf enumerator1 Is IDisposable) Then
                            TryCast(enumerator1, IDisposable).Dispose()
                        End If
                    End Try
                    Return
                End While
            Finally
                If (TypeOf enumerator Is IDisposable) Then
                    TryCast(enumerator, IDisposable).Dispose()
                End If
            End Try
            Try
                enumerator1 = Me.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.ImportCosts.GetEnumerator()
                While enumerator1.MoveNext()
                    current = DirectCast(enumerator1.Current, ImportCost)
                    If (current.Apportioned) Then
                        Continue While
                    End If
                    current.AddShipmentLineToApportion(line)
                End While
            Finally
                If (TypeOf enumerator1 Is IDisposable) Then
                    TryCast(enumerator1, IDisposable).Dispose()
                End If
            End Try
        End Sub

        Protected Overrides Sub iSave()
            Throw New NotImplementedException()
        End Sub


Anyway,
so once partno is set to line basically they are pointing to the same block of memory and are the same object.
is basically saying that setting all the properties of partNo magically also sets the properties of line. So why have 2 objects identical to each other? Why this
Code: Select all
Me.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.Lines.Add(line)
and not
Code: Select all
Me.PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.Lines.Add(partNo)

Is there a possibility that the readonly properties I mentioned are not readonly for partNo but are readonly for line? How does that work when they're identical objects, wouldn't they both be readonly on those properties?

Re: Shipment import from CSV or Excel

PostPosted: Tue Jun 17, 2025 4:57 pm
by SBarnes
DannyC wrote:

Hmmm, I'm not so sure.
[/quote]

I am because I've seen it before. the decompiled visual basic code is equally interpreted it's not the original code, Mike or Scott might be able to provide the raw code for this, but it will prove I am right.

They are the same object please read this https://learn.microsoft.com/en-us/dotne ... ence-types and this https://www.c-sharpcorner.com/article/v ... n-c-sharp/, basically a reference type is nothing more than a pointer to a block of memory so two reference variables can be assigned to the same block of memory.

Read only properties on an object are read only regardless of which variable you use, the only way you are going to set them is by using reflection, there is no difference depending on the variable.

Re: Shipment import from CSV or Excel

PostPosted: Tue Jun 17, 2025 6:21 pm
by DannyC
Read only properties on an object are read only regardless of which variable you use

Using the QuantityOrdered as a test, I can't find any backing field using Reflection.

I think it will need Mike or Scott's input to answer & help me understand how to set those readonly properties. Reflection isn't helping.
The JustDecompile code for AddToShipmentLines() sets QuantityOrdered (and the other readonly properties) by a simple assignment
Code: Select all
partNo.QuantityOrdered = this.QuantityOrdered;

How does that work if partNo.QuantityOrdered is readonly?

if Mike is able, can you explain?
Ideally, if I have a PartNo and purchase orderno from Excel, how could I populate the shipment lines tab (sample plugin or is that pushing it :) )

Re: Shipment import from CSV or Excel

PostPosted: Tue Jun 17, 2025 7:21 pm
by Mike.Sheen
The source VB for the AddToShipmentLines method of the JiwaLandedCost\Shipment\Line.vb class is:

Code: Select all
Public Sub AddToShipmentLines()
    Dim newShipmentLine As Line = Manager.CollectionItemFactory.CreateCollectionItem(Of Line)()

    With newShipmentLine
        .PurchaseOrderLine.ReadRecord(Me.RecID)

        If Not IN_SupplierWarehouse_RecID Is Nothing AndAlso IN_SupplierWarehouse_RecID.Trim.Length > 0 Then
            .SupplierWarehouse.ReadRecord(IN_SupplierWarehouse_RecID)
        End If

        If Not IN_Creditor_RecID Is Nothing AndAlso IN_Creditor_RecID.Trim.Length > 0 Then
            .Supplier.ReadRecord(IN_Creditor_RecID)
        End If

        If Not .Supplier Is Nothing AndAlso Not .Supplier.CreditorID Is Nothing AndAlso .Supplier.CreditorID.Trim.Length > 0 Then
            .Creditor.ReadRecord(.Supplier.CreditorID)
        ElseIf newShipmentLine.IsNonInventory Then
            .Creditor.ReadRecord(PurchaseOrderLines.PurchaseOrder.PurchaseOrder.Creditor.CreditorID)
        End If

        If Not IN_Main_RecID Is Nothing AndAlso IN_Main_RecID.Trim.Length > 0 Then
            .Inventory.ReadRecord(IN_Main_RecID)
        End If
        .Inventory.PartNo = PartNo
        .Inventory.Description = Description

        If Not PO_Classification_RecID Is Nothing AndAlso PO_Classification_RecID.Trim.Length > 0 Then
            .PurchaseOrderClassification.ReadRecord(PO_Classification_RecID)
        End If

        .QuantityOrdered = QuantityOrdered
        If .QuantityOrdered > .PurchaseOrderLine.QuantityDelivered Then
            .QuantityThisShipment = .QuantityOrdered - .PurchaseOrderLine.QuantityDelivered
        Else
            .QuantityThisShipment = 0
        End If

        .OrderedCost = OrderedCost
        .FXOrderedCost = SuppliersCost

        .UnitCostExTax = OrderedCost
        .FXRate = Lines.PurchaseOrder.PurchaseOrder.Creditor.CurrentFXRate
        .FXUnitCostExTax = SuppliersCost
        If _TX_Main_RecID IsNot Nothing AndAlso _TX_Main_RecID.Trim.Length > 0 Then
            .TaxRate.Read(_TX_Main_RecID)
        End If
        .TaxAmount = _TaxAmount
        .UnitCostIncTax = IncPrice
        .LineTotalExTax = _LineTotalExTax
        .LineTotalIncTax = _LineTotalIncTax
        .FXLineTotalExTax = _FXTotal

        .OriginalUnitCostExTax = .UnitCostExTax
        .OriginalLandedCost = 0
        .OriginalSumOfApportionedCosts = 0
        .PurchaseOrdersKey = PurchaseOrderLines.PurchaseOrder.RecID
        .InvoicesKey = ""
        .ChangeSourceIsFromPurchaseOrderLine = True
        .UnitChanged = Me.UnitChanged
        .FXChanged = Me.FXChanged
        .ExChanged = Me.ExChanged
        .TaxRateChanged = Me.TaxRateChanged
    End With

    PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.Lines.Add(newShipmentLine)
    'newShipmentLine.CalculateLandedCostTotal(Line.LandedCostCalculationSource.FromUnit) 'This calculates LandedCost and LandedCostTotal
    newShipmentLine.CalculateLandedCostTotal(newShipmentLine.UnitChanged)

    For Each existinginvoice As Invoice In PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.Invoices
        If existinginvoice.Creditor.CreditorID = PurchaseOrderLines.PurchaseOrder.PurchaseOrder.Creditor.CreditorID And existinginvoice.Invoiced = False Then
            newShipmentLine.SetInvoicesKey(existinginvoice.RecID)
            existinginvoice.DoLineCalculations()
            Exit For
        End If
    Next

    'Add apportion entry (zeroed at this stage) for any pre-exiting import costs.
    For Each existingImportCost As ImportCost In PurchaseOrderLines.PurchaseOrder.PurchaseOrders.Shipment.ImportCosts
        If existingImportCost.Apportioned = False Then
            existingImportCost.AddShipmentLineToApportion(newShipmentLine)
        End If
    Next
End Sub


The QuantityOrdered Property Getter and Setter is simply:
Code: Select all
Public Property QuantityOrdered() As Decimal
    Get
        Return _QuantityOrdered
    End Get
    Friend Set(ByVal Value As Decimal)
        _QuantityOrdered = Value
        NotifyPropertyChanged("QuantityOrdered")
    End Set
End Property


You should be able to use reflection to set that - what have you tried that does not work?

Re: Shipment import from CSV or Excel

PostPosted: Tue Jun 17, 2025 8:02 pm
by DannyC
You should be able to use reflection to set that - what have you tried that does not work?


Code: Select all
JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line shipmentLine = shipment.Manager.CollectionItemFactory.CreateCollectionItem<JiwaFinancials.Jiwa.JiwaLandedCost.Shipment.Line>();
System.Type type = shipmentLine.GetType();
System.Reflection.FieldInfo field = type.GetField("<QuantityOrdered>_QuantityOrdered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

returns null for 'field'.
That seems to be the appropriate syntax but maybe it's wrong.