D365 How to Finalize a PO

public void finaliseInvoice(PurchTable _purchTable)
        {
            Args args = new Args();
            str parmStr = "PurchFinalizeService.finalizePurchOrder";

            args.parm(parmStr);
            args.parmEnum(SysOperationExecutionMode::Synchronous);
            args.record(_purchTable);

            PurchFinalizeServiceController controller =  PurchFinalizeServiceController::newFromArgs(args);
            
            controller.parmLoadFromSysLastValue(false);

            PurchFinalizeContract contract = controller.getDataContractObject();

            contract.parmClosingDate(systemDateGet());
            contract.parmOnlyCompletedLine(true);

            controller.parmExecutionMode(SysOperationExecutionMode::Synchronous);
            controller.parmShowDialog(false);
            controller.startOperation();
        }

D365 How to import a csv file in batch mode

public class UpdatePurchLineFinDimPeriodic_DEV extends RunBaseBatch
{
    // Packed variables
    Filename        filename;
    SharedServiceUnitURL filePath;

    // Dialog fields
    DialogRunbase		dialog;
    FileUploadBuild     dialogFileUpload;
    FileUpload          fileUpload;
    FileUploadTemporaryStorageResult fileUploadResult;
    System.IO.Stream    stream;

	// Other variables
    AsciiStreamIo       lineFile;
    int					totalLineRecords;

    private const str FileUploadName = 'FileUpload';
    private const str OkButtonName = 'OkButton';

    #define.Delimeter(",")

    #define.CurrentVersion(1)
    #localmacro.CurrentList
        filename,
		filePath
    #endmacro

    public boolean canGoBatchJournal()
    {
        return false;
    }

    public Object dialog()
    {
        DialogGroup      dialogGroup;
        FormBuildControl formBuildControl;       
        ;
       
        dialog = super();
        dialogGroup = dialog.addGroup("File path");
        formBuildControl = dialog.formBuildDesign().control(dialogGroup.name());
       
        dialogFileUpload = formBuildControl.addControlEx(classstr(FileUpload), FileUploadName);
        dialogFileUpload.style(FileUploadStyle::MinimalWithFilename);
        dialogFileUpload.baseFileUploadStrategyClassName(classstr(FileUploadTemporaryStorageStrategy));
        dialogFileUpload.fileTypesAccepted(".csv");
        dialogFileUpload.fileNameLabel("@SYS308842");

        return dialog;
    }

    /// <summary>
    /// Disables the dialog Ok button until the file upload is complete.
    /// </summary>
    /// <param name="_dialog">The <c>Runbase</c> dialog object.</param>
    public void dialogPostRun(DialogRunbase _dialog)
    {
        fileUpload = _dialog.formRun().control(_dialog.formRun().controlId('FileUpload'));
        fileUpload.notifyUploadCompleted += eventhandler(this.uploadCompleted);
        this.setDialogOkButtonEnabled(_dialog, false);
    }

    /// <summary>
    /// After the file has been uploaded, the Ok button is enabled.
    /// </summary>
    public void uploadCompleted()
    {
        filename = fileUpload.fileName();
 
        this.setDialogOkButtonEnabled(dialog, true);
         
        fileUploadResult = fileUpload.getFileUploadResult();
        filePath = fileUploadResult.getDownloadUrl();

        fileUpload.notifyUploadCompleted -= eventhandler(this.UploadCompleted);
    }

    /// <summary>
    /// Enables or disables the dialog Ok button.
    /// </summary>
    /// <param name = "_dialog">The <c>Runbase</c> dialog object.</param>
    /// <param name = "_isEnabled">Indicates to enable or disable the Ok button.</param>
    protected void setDialogOkButtonEnabled(DialogRunbase _dialog, boolean _isEnabled)
    {
        FormControl okButtonControl = _dialog.formRun().control(_dialog.formRun().controlId('OkButton'));
 
        if (okButtonControl)
        {
            okButtonControl.enabled(_isEnabled);
        }
    }

    public boolean getFromDialog()
    {
    ;
        return super();
    }

    public boolean init()
    {
        return true;
    }

    protected void new()
    {
        super();
    }

    public container pack()
    {
        return [#CurrentVersion,#CurrentList];
    }

    /// <summary>
    ///    Contains the code that does the actual job of the class.
    /// </summary>
    public void run()
    {
        #OCCRetryCount
        if (! this.validate())
            throw error("");

        try
        {
            ttsbegin;

            this.runImport();

            ttscommit;

            info(strFmt("@SYS74545",totalLineRecords, tableStr(PurchLine)));
        }
        catch (Exception::Deadlock)
        {
            retry;
        }
        catch (Exception::UpdateConflict)
        {
            if (appl.ttsLevel() == 0)
            {
                if (xSession::currentRetryCount() >= #RetryNum)
                {
                    throw Exception::UpdateConflictNotRecovered;
                }
                else
                {
                    retry;
                }
            }
            else
            {
                throw Exception::UpdateConflict;
            }
        }
    }

    private void runImport()
	{
		//create purch line
		this.openPurchLine();
		this.updatePurchLine();
	}

    private void openPurchLine()
	{
        lineFile = AsciiStreamIo::constructForRead(File::UseFileFromURL(filePath));

        //stream = fileUploadResult.openResult();
        //lineFile = AsciiStreamIo::constructForRead(stream);
        lineFile.inFieldDelimiter(#Delimeter);
    }

    private void updatePurchLine()
	{
        container   record;
        PurchLine   purchLine;
        InventDim   inventDim;
        
        PurchId         line_PurchId;
        LineNum			line_LineNum;
        ItemId          line_ItemId;
		AMDeviceId      line_DeviceId;
        DimensionValue  line_Department;

        #define.line_PurchId(1)
        #define.line_LineNum(2)
        #define.line_ItemId(3)
        #define.line_DeviceId(4)
        #define.line_Department(5)

        //read first line
        record = lineFile.read();
        
        while(lineFile.status() ==  IO_Status::Ok)
        {
			record = lineFile.read();

			if(!record)
				break;

            line_PurchId        = conPeek(record, #line_PurchId);
            line_LineNum		= conPeek(record, #line_LineNum);
            line_ItemId         = conPeek(record, #line_ItemId);
            line_DeviceId       = conPeek(record, #line_DeviceId);
            line_Department     = conPeek(record, #line_Department);

			line_PurchId		= strRTrim(strLTrim(line_PurchId));
			line_ItemId         = strRTrim(strLTrim(line_ItemId));
			line_DeviceId       = strRTrim(strLTrim(line_DeviceId));
			line_Department		= strRTrim(strLTrim(line_Department));
        
            select firstOnly forupdate * from purchLine
                where purchLine.PurchId == line_PurchId 
                && purchLine.LineNumber == line_LineNum;
			
			if (purchLine)
			{
                OMOperatingUnit omOperatingUnit;

                select RecId from omOperatingUnit
                    where omOperatingUnit.OMOperatingUnitNumber == line_Department 
                    && omOperatingUnit.OMOperatingUnitType == OMOperatingUnitType::OMDepartment;
 
                if (omOperatingUnit.RecId)
				{
                    Name dimAttrName = "Department";
                    purchLine.DefaultDimension = UtilDimensionHelper_INT::setDefaultDimensionValue(purchLine.DefaultDimension, dimAttrName, line_Department);
                    purchLine.doUpdate();
                    totalLineRecords++;
				}
            }//end purchline
		}//end readLine
	}

    public boolean runsImpersonated()
    {
        return true;
    }

    public boolean unpack(container packedClass)
    {
        Version version = RunBase::getVersion(packedClass);
    ;
        switch (version)
        {
            case #CurrentVersion:
                [version,#CurrentList] = packedClass;
                break;
            default:
                return false;
        }

        return true;
    }

    public boolean validate(Object _calledFrom = null)
    {
        if (false)
            return checkFailed("");

        return true;
    }

    static UpdatePurchLineFinDimPeriodic_INT construct()
    {
        return new UpdatePurchLineFinDimPeriodic_INT();
    }

    static ClassDescription description()
    {
        return "@INT:UpdatePurchOrderLineFinDim";
    }

    static void main(Args args)
    {
        UpdatePurchLineFinDimPeriodic_INT    updatePurchLineFinDim;
    ;
        updatePurchLineFinDim = UpdatePurchLineFinDimPeriodic_INT::construct();

        if (updatePurchLineFinDim.prompt())
            updatePurchLineFinDim.runOperation();
    }

    protected boolean canRunInNewSession()
    {
        return false;
    }

}