Showing posts with label sharePoint. Show all posts
Showing posts with label sharePoint. Show all posts

Monday, November 17, 2025

Import of custom bank statements from share point folders

    

This class handles the import of custom bank statements for S_Bank and P_Bank from their respective SharePoint folders as part of the financial integration process.

public class ImportPaymentFileService extends SysOperationServiceBase 

    CompanyBankAccountId    bankAccountId; 

    BankAccountTable        bankAccountTable; 

    container               outputCont; 

    InfologData             infologData; 

     

  

    #define.CSVFormat('.csv') 

  

    /// <summary> 

    ///   Executes the process. 

    /// </summary> 

    /// <param name = "_contract">Buffer of  _ImportPaymentFileContract</param> 

     public void process ( _ImportPaymentFileContract _contract) 

    { 

         _DownloadFileFromSharepoint  downloadFileFromSharepointdown;  

        infologData = conNull(); 

        bankAccountId = _contract.parmCompanyBankAccountId(); 

        bankAccountTable = BankAccountTable::find(bankAccountId); 

        if(this.validateParameters()) 

        { 

            downloadFileFromSharepointdown = new  _DownloadFileFromSharepoint(); 

            downloadFileFromSharepointdown.parmSharePointURL(this.getSharePointURL( _CustomFileImportStatus::None)); 

            this.initiate(this.parmOutputCont(downloadFileFromSharepointdown.downloadFile())); 

        } 

        else 

        { 

            infologData = InfoLog.export(); 

             _CustomStmtA   uditLog::insertLog("", bankAccountTable.AccountID, "", NoYes::No, NoYes::Yes, DateTimeUtil::getSystemDateTime(),  _CustomFileImportStatus::Error, infologData); 

        }        

  

    } 

  

    /// <summary> 

    ///   Initiate the process. 

    /// </summary> 

    /// <param name = "_container">Container holds all the file details</param> 

    public void initiate(container _container) 

    { 

        System.IO.MemoryStream conMemoryStream; 

  

        if(conLen(_container) > 0) 

        { 

            for(int value = 1; value <= conLen(_container); value++) 

            { 

                container memoryCont = conPeek(_container, value); 

                conMemoryStream = new System.IO.MemoryStream(); 

                conMemoryStream = conPeek(memoryCont, 2); 

                str fileName = conPeek(memoryCont, 1); 

                str extension; 

                str path; 

                str name; 

  

                [path, name, extension] = fileNameSplit(fileName);                

                 

                Microsoft.Dynamics.AX.Framework.FileManagement.DocumentLocation documentLocation = conPeek(memoryCont, 3); 

                try 

                { 

                    ttsbegin; 

  

                    infologData = conNull(); 

  

                    BankStatementId bankStatementId; 

                    AsciiStreamIo asciFile  =  AsciiStreamIo::constructForRead(conMemoryStream); 

                    if(asciFile) 

                    { 

                        if(asciFile.status()) 

                        { 

                            throw error("@Deloitte: _FileError"); 

                        } 

                        if(extension != #CSVFormat) 

                        { 

                            throw error("@Deloitte: _FormatError"); 

                        } 

                        asciFile.inFieldDelimiter(','); 

                        //asciFile.inRecordDelimiter('\r\n'); 

                        asciFile.inRecordDelimiter('\n'); 

                    } 

                    switch(bankAccountTable. _CustomBankStmtAccount) 

                    { 

                        case  _CustomBankStmtAccount:: S_bank: 

                            bankStatementId = this.insert S_bankBankStatement(asciFile); 

                            break; 

                        case  _CustomBankStmtAccount::P_bank_bank: 

                            bankStatementId = this.insertP_bank_bankBankStatement(asciFile); 

                            break; 

  

                        default: 

                            break; 

                             

                    } 

                    if(!bankStatementId) 

                    { 

                        throw error("@Deloitte: _ServiceFileError", fileName); 

                    } 

                    this.moveFile( _CustomFileImportStatus::Archive, conMemoryStream, fileName, documentLocation); 

                     _CustomStmtAuditLog::insertLog(fileName, bankAccountTable.AccountID, bankStatementId, NoYes::Yes, NoYes::No, DateTimeUtil::getSystemDateTime(),  _CustomFileImportStatus::Archive, infologData); 

                    info(strFmt("@Deloitte: _SuccessInfo", bankStatementId)); 

                    ttscommit; 

                } 

                catch 

                { 

                    this.moveFile( _CustomFileImportStatus::Error, conMemoryStream, fileName, documentLocation); 

                    infologData = InfoLog.export(); 

                     _CustomStmtAuditLog::insertLog(fileName, bankAccountTable.AccountID, "", NoYes::No, NoYes::Yes, DateTimeUtil::getSystemDateTime(),  _CustomFileImportStatus::Error, infologData); 

                } 

  

  

            } 

        } 

        else 

        { 

            error(strFmt("@Deloitte: _NoFileError", this.getSharePointURL( _CustomFileImportStatus::None), bankAccountTable.AccountID)); 

            infologData = InfoLog.export(); 

             _CustomStmtAuditLog::insertLog("", bankAccountTable.AccountID, "", NoYes::No, NoYes::Yes, DateTimeUtil::getSystemDateTime(),  _CustomFileImportStatus::Error, infologData); 

        } 

    } 

  

    /// <summary> 

    /// Get the sharepoint url 

    /// </summary> 

    /// <param name = "_status"> _CustomFileImportStatus.</param> 

    /// <returns>sharepoint url</returns> 

    private str getSharePointURL( _CustomFileImportStatus _status) 

    { 

        DocuType    docuType; 

        str         sharepointURL; 

        str         docuURL; 

  

        docuType = DocuType::find(bankAccountTable. _DocuTypeId); 

  

        if(!docuType) 

            throw Error (strfmt(" _DocuError")); 

  

        docuURL = docuType.sharePointUrl(); 

  

        if(!docuURL) 

        { 

            throw Error(strFmt("@Deloitte: _URLError"), docuType.TypeId); 

        } 

        if(_status ==  _CustomFileImportStatus::Error && bankAccountTable. _ErrorSharePointPath) 

        { 

            sharepointURL = strFmt("@Deloitte: _URL",docuURL, bankAccountTable. _ErrorSharePointPath); 

        } 

        else if(_status ==  _CustomFileImportStatus::Archive && bankAccountTable. _ArchiveSharepointPath) 

        { 

            sharepointURL = strFmt("@Deloitte: _URL",docuURL, bankAccountTable. _ArchiveSharepointPath); 

        } 

        else if(_status ==  _CustomFileImportStatus::None && bankAccountTable. _InboundSharepointPath) 

        { 

            sharepointURL = strFmt("@Deloitte: _URL",docuURL, bankAccountTable. _InboundSharepointPath); 

        } 

        else 

        { 

            sharepointURL = docuURL; 

        } 

  

        return sharepointURL; 

         

    } 

  

    /// <summary> 

    /// Get the connection string 

    /// </summary> 

    /// <param name = "_status"> _CustomFileImportStatus.</param> 

    /// <returns>container based on status</returns> 

    public container getConnectionDetails( _CustomFileImportStatus _status) 

    { 

         _DownloadFileFromSharepoint  downLoadFile =  _DownloadFileFromSharepoint::construct(); 

        downLoadFile.parmSharePointURL(this.getSharePointURL(_status)); 

        return downLoadFile.getConnectionDetails(downLoadFile.connectionString()); 

    } 

  

    /// <summary> 

    /// Upload the file to sharepoint 

    /// </summary> 

    /// <param name = "_status"> _CustomFileImportStatus.</param> 

    /// <param name = "_conMemoryStream">Memory strem of a file.</param> 

    /// <param name = "_fileName">File name</param> 

    /// <param name = "_documentLocation">location to move the file</param> 

    public void moveFile( _CustomFileImportStatus status, System.IO.MemoryStream conMemoryStream, FileName _fileName, 

                                            Microsoft.Dynamics.AX.Framework.FileManagement.DocumentLocation _documentLocation) 

    { 

        if(_conMemoryStream && _fileName) 

        { 

             

            container                                                                           binData; 

            Binary                                                                              binaryData; 

            System.Byte[]                                                                       localbinData; 

            System.IO.Stream                                                                    localStream; 

            Microsoft.Dynamics.AX.Framework.FileManagement.SharePointDocumentStorageProvider    saveprovider; 

            Microsoft.Dynamics.AX.Framework.FileManagement.DocumentLocation                     savedocumentLocation = new Microsoft.Dynamics.AX.Framework.FileManagement.DocumentLocation(); 

            container                                                                           connectionCon = this.getConnectionDetails(_status); 

            str                                                                                 extId = xUserInfo::getCurrentUserExternalId(); 

             

  

            saveprovider = new Microsoft.Dynamics.AX.Framework.FileManagement.SharePointDocumentStorageProvider(conPeek(connectionCon, 1), conPeek(connectionCon, 2), conPeek(connectionCon, 3), extId);//"cpaaustralia.sharepoint.com", "sites/CPAD365FO", "Shared Documents/Upload", extId); 

            saveprovider.ProviderId = DocuStorageProviderType::SharePoint; 

  

            binaryData = Binary::constructFromMemoryStream(_conMemoryStream); 

  

            if(binaryData) 

            { 

                binData = binaryData.getContainer(); 

            } 

  

            for(int i = 0; i < conLen(binData); i++) 

            { 

                localbinData = conPeek(binData, i+1); 

                localStream  = new System.IO.MemoryStream(localbinData); 

            } 

            boolean fileExists = saveprovider.FileExists(_fileName); 

            if(fileExists) 

            { 

                if(localStream.Length > 0) 

                { 

                    savedocumentLocation = saveprovider.SaveFileWithOverwrite(newGuid(), _fileName, System.Web.MimeMapping::GetMimeMapping(_fileName), localStream); 

                    saveprovider.DeleteFile(_documentLocation); 

                } 

            } 

            else 

            { 

                savedocumentLocation = saveprovider.SaveFile(newGuid(), _fileName, System.Web.MimeMapping::GetMimeMapping(_fileName), localStream); 

                if(saveprovider.FileExists(_fileName)) 

                { 

                    saveprovider.DeleteFile(_documentLocation); 

                } 

            } 

        } 

  

    } 

  

    /// <summary> 

    /// Create  S_bank bank statement 

    /// </summary> 

    /// <param name = "_asciFile">Asci file.</param> 

    /// <returns>Bank Statement id</returns> 

    private BankStatementId insert S_bankBankStatement(AsciiStreamIo _asciFile) 

    { 

        FromDateTime                statementFromdate = DateTimeUtil::getSystemDateTime(); 

        ToDateTime                  statementTodate = DateTimeUtil::getSystemDateTime(); 

        container                   record; 

        RefRecId                    bankStmtISOHeaderRecid; 

        BankStmtISOAccountStatement statement; 

        boolean                     bankStatementHeaderCreated; 

        boolean                     lineCreated; 

        container                   statementLineCont; 

        int                         row = 0; 

        str                         chargeId; 

        while(!_asciFile.status()) 

        { 

            record = _asciFile.read(); 

            row += 1; 

            if(conLen(record) && row >=2) 

            { 

                statementLineCont += [record]; 

                if(!bankStatementHeaderCreated) 

                { 

                    statement = this.insertIntoBankStmtISOHeader(statementFromdate, statementTodate); 

                    bankStatementHeaderCreated = true; 

                    bankStmtISOHeaderRecid = statement.RecId; 

                } 

            } 

        } 

        //insert statement lines 

        if(conLen(statementLineCont) && bankStatementHeaderCreated) 

        { 

            this.insert S_bankBankStmtISOReportEntry(bankStmtISOHeaderRecid, statementLineCont); 

        } 

        lineCreated = this.updateStatementDate(statement.RecId, NoYes::Yes); 

        if(!lineCreated) 

        { 

            throw error ("@Deloitte: _LineError"); 

        } 

        //insert cash balance 

        if(statement) 

        { 

            this.insertIntoBankStmISOCash(statement); 

             

        } 

  

        return statement.Identification; 

  

    } 

  

    /// <summary> 

    /// Update bank statement header 

    /// </summary> 

    /// <param name = "_statementRecId">RecID of bank statement header.</param> 

    /// <param name = "_updateDate">Update date in header.</param> 

    /// <returns>True if lines created;otherwise false</returns> 

    private boolean updateStatementDate(RefRecId statementRecId, boolean updateDate) 

    { 

        BankStmtISOReportEntry  reportEntryMax; 

        BankStmtISOReportEntry  reportEntryMin; 

        int                   totalLines; 

        BankStmtISOAccountStatement statement = BankStmtISOAccountStatement::find(_statementRecId); 

  

        if(statement) 

        { 

            if(_updateDate) 

            { 

                select firstonly BookingDateTime from reportEntryMax 

                    order by BookingDateTime desc 

                    where reportEntryMax.BankStmtISOAccountStatement == _statementRecId; 

                 

                select firstonly BookingDateTime from reportEntryMin 

                    order by BookingDateTime asc 

                    where reportEntryMin.BankStmtISOAccountStatement == _statementRecId; 

  

                statement.FromDateTime = reportEntryMin.BookingDateTime; 

                statement.ToDateTime = reportEntryMax.BookingDateTime; 

            } 

                        

            statement.selectForUpdate(true); 

            totalLines = int642int(statement.calcTotalLines()); 

            statement.TotalEntriesNumberOfEntries = totalLines; 

            ttsbegin; 

            statement.update(); 

            ttscommit; 

        } 

  

        return totalLines; 

    } 

  

    /// <summary> 

    /// Create  S_bank bank statement lines 

    /// </summary> 

    /// <param name = "_bankStmtISOHeaderRecid">RecID of bank statement header.</param> 

    /// <param name = "_statementLineCon">statement lines container.</param> 

    private void insert S_bankBankStmtISOReportEntry(RefRecId bankStmtISOHeaderRecid, container statementLineCon) 

    { 

        BankStmtISOReportEntry reportEntry; 

        Amount                 netAmount; 

        utcdatetime            lastBookingDateTime; 

  

        if(!_bankStmtISOHeaderRecid || conLen(_statementLineCon) < 0) 

        { 

            return; 

        } 

        for(int value = 1; value <= conLen(_statementLineCon) ; value++) 

        { 

            container   statementLineValCon; 

            AmountCur   chargeAmount; 

            DebitCredit chargeIndicator, amountIndicator; 

            AmountCur   grossAmt; 

            utcdatetime bookingDateTime; 

            utcdatetime feeBookingDateTime; 

            container   lineCon; 

  

            lineCon = conPeek(_statementLineCon, value); 

            statementLineValCon = this.returnRecordContainer(lineCon); 

  

            grossAmt = str2Num(conPeek(statementLineValCon, 7)); 

            netAmount += str2Num(conPeek(statementLineValCon, 9)); 

            bookingDateTime = this.getDateTime(conPeek(statementLineValCon, 1), NoYes::No); 

            lastBookingDateTime = bookingDateTime; 

            amountIndicator = DebitCredit::Debit; 

            if(grossAmt < 0) 

            { 

                amountIndicator = DebitCredit::Credit; 

            } 

            //Aaditya Purohit, MMFS36: General  S_bank payment, 25/7/2024 -->  

            //CPA: NR: 20240901: FNO-756: CR  S_bank and P_bank_bank statements imported to FO 

            if(grossAmt > 0 && conPeek(statementLineValCon, 11) != "") 

            { 

                this.insert S_bankReportEntry(_bankStmtISOHeaderRecid, statementLineValCon, grossAmt, amountIndicator, bookingDateTime, NoYes::No); 

            } 

            else if(grossAmt > 0 && conPeek(statementLineValCon, 11) == "") 

            { 

                this.insert S_bankReportEntry(_bankStmtISOHeaderRecid, statementLineValCon, grossAmt, amountIndicator, bookingDateTime, NoYes::Yes); 

            } 

            else if(grossAmt < 0 && conPeek(statementLineValCon, 11) == "") 

            { 

                this.insert S_bankReportEntry(_bankStmtISOHeaderRecid, statementLineValCon, grossAmt, amountIndicator, bookingDateTime, NoYes::Yes); 

            } 

            else if(grossAmt < 0 && conPeek(statementLineValCon, 11) != "") 

            { 

                this.insert S_bankReportEntry(_bankStmtISOHeaderRecid, statementLineValCon, grossAmt, amountIndicator, bookingDateTime, NoYes::No); 

            } 

            //CPA: NR: 20240901: FNO-756: CR  S_bank and P_bank_bank statements imported to FO 

            chargeAmount = str2Num(conPeek(statementLineValCon, 8)); 

            chargeIndicator = DebitCredit::Credit; 

            if(chargeAmount < 0) 

            { 

                chargeIndicator = DebitCredit::Debit; 

            } 

            if(chargeAmount != 0) 

            { 

                //feeBookingDateTime = this.getDateTime(conPeek(statementLineValCon, 1), NoYes::No); 

                this.insert S_bankReportEntry(_bankStmtISOHeaderRecid, statementLineValCon, chargeAmount, chargeIndicator, bookingDateTime, NoYes::Yes); 

            } 

            //Aaditya Purohit, MMFS36: General  S_bank payment, 25/7/2024 <-- 

        } 

  

        if(netAmount) 

        { 

            BankStmtISOReportEntry lastReportEntry;        

            lastReportEntry.clear(); 

  

            lastReportEntry.initValue(); 

            lastReportEntry.BankStmtISOAccountStatement = _bankStmtISOHeaderRecid; 

            lastReportEntry.BookingDateTime = lastBookingDateTime; 

            lastReportEntry.BankStatementLineStatus = BankStatementLineStatus::Booked; 

            lastReportEntry.Amount = abs(netAmount); 

            lastReportEntry.AmountCreditDebitIndicator = DebitCredit::Credit; 

            if(netAmount < 0) 

            { 

                lastReportEntry.AmountCreditDebitIndicator = DebitCredit::Debit; 

            } 

            // add by ratna #MMFS-30 payout litne reference on 07-09-2024             

            lastReportEntry.EntryReference = strFmt("@Deloitte:  S_bankPayout",date2Str(DateTimeUtil::date(lastBookingDateTime),123,DateDay::Digits2,DateSeparator::None,DateMonth::Digits2,DateSeparator::None,DateYear::Digits4)); 

            //end by ranta #MMFS-30 

            lastReportEntry.insert(); 

  

            lastReportEntry.reread(); 

            this.insertIntoBankStatementLineBankDocument(lastReportEntry, NoYes::Yes); 

            //BankStmtISOReportEntry::markNewBankDocument(lastReportEntry.RecId, NoYes::Yes); 

             

        } 

    } 

  

    /// <summary> 

    /// Create  S_bank bank statement lines 

    /// </summary> 

    /// <param name = "_bankStmtISOHeaderRecid">RecID of bank statement header.</param> 

    /// <param name = "_valueCon">statement lines container.</param> 

    /// <param name = "_amount">Gross amount.</param> 

    /// <param name = "_indicator">Amount indicator.</param> 

    /// <param name = "_bookingDatetime">line booking date time.</param> 

    /// <param name = "_isNew">statement Is new document.</param> 

    private void insert S_bankReportEntry(RefRecId bankStmtISOHeaderRecid, container valueCon, Amount amount, DebitCredit indicator, utcdatetime bookingDatetime, NoYes isNew) 

    { 

        BankStmtISOReportEntry reportEntry; 

        container              valueCon = _valueCon; 

  

        if(conLen(valueCon)) 

        { 

            reportEntry.clear(); 

  

            reportEntry.initValue(); 

            reportEntry.BankStmtISOAccountStatement = _bankStmtISOHeaderRecid; 

            //ratna, MMFS36: General  S_bank payment, 16/8/2024 --> 

            reportEntry.EntryReference = conPeek(valueCon, 14); 

            reportEntry.BookingDateTime = _bookingDatetime; 

            reportEntry.BankStatementLineStatus = BankStatementLineStatus::Booked; 

            reportEntry.ReferenceNumber = conPeek(valueCon, 13); 

            reportEntry. _Source_Id = conPeek(valueCon, 15); 

            reportEntry. _AdjustmentNoteNum = conPeek(valueCon, 17); 

            reportEntry. _CPAAustraliaIdStr = conPeek(valueCon, 16); 

            reportEntry. _EnvironmentPlatform = conPeek(valueCon, 18); 

            //ratna , MMFS36: General  S_bank payment, 16/8/2024 <-- 

            //reportEntry.BankDocumentNumber = conPeek(valueCon, 27); 

            reportEntry.Amount = abs(_amount); 

            reportEntry.AmountCreditDebitIndicator = DebitCredit::Debit; 

            reportEntry.AmountCreditDebitIndicator = _indicator; 

            //reportEntry.IsNewBankDocument = _isNew; 

            reportEntry.insert(); 

  

            reportEntry.reread(); 

             

            if (_isNew) 

            { 

                 

                // comented by ratna #MMFS-27 double posting sub ledger issue related on 01-07-2024 

               // this.insertIntoBankStatementLineBankDocument(reportEntry, NoYes::No); 

               // End by ratna #MMFS-27 

                // The method below will update the IsNewBankDocument field 

                BankStmtISOReportEntry::markNewBankDocument(reportEntry.RecId, _isNew); 

            }             

        } 

    } 

  

    /// <summary> 

    /// Gets datetime 

    /// </summary> 

    /// <param name = "_dateTimeStr">String date/time from csv.</param> 

    /// <param name = "_isUTC">Is it utc string.</param> 

    /// <returns>utc date time</returns> 

    private utcdatetime getDateTime(str dateTimeStr, boolean isUTC) 

    { 

        List            list = new List(Types::String); 

        container       packedList; 

        ListIterator    iterator; 

        int             i; 

        str             dateStr; 

        str             timeStr; 

        str             newdateStr; 

        int             timeInt; 

        date            dateValue; 

        str             datetimeStr = _dateTimeStr; 

        utcdatetime     dateTime; 

  

        if(datetimeStr) 

        { 

            list = Global::strSplit(datetimeStr," "); 

            iterator = new ListIterator(list); 

  

            while(iterator.more()) 

            { 

                packedList += iterator.value(); 

                iterator.next(); 

            } 

  

            if(conLen(packedList)>0) 

            { 

                newdateStr = conPeek(packedList,1); 

                timeStr = conPeek(packedList,2); 

            } 

  

            timeInt = str2Time(timeStr); 

            dateValue = str2Date(newdateStr, 321); 

        } 

        if(_isUTC) 

        { 

            dateTime = DateTimeUtil::newDateTime(dateValue, timeInt);             

        } 

        else 

        { 

            dateTime =  DateTimeUtil::removeTimeZoneOffset(DateTimeUtil::newDateTime(dateValue, timeInt), DateTimeUtil::getUserPreferredTimeZone()); 

        } 

         

        return dateTime; 

  

    } 

  

    /// <summary> 

    /// Create P_bank_bank bank statement 

    /// </summary> 

    /// <param name = "_asciFile">Asci file.</param> 

    /// <returns>Bank Statement id</returns> 

    private BankStatementId insertP_bank_bankBankStatement(AsciiStreamIo _asciFile) 

    { 

        FromDateTime                statementFromdate; 

        ToDateTime                  statementTodate; 

        container                   record; 

        RefRecId                    bankStmtISOHeaderRecid; 

        BankStmtISOAccountStatement statement; 

        boolean                     bankStatementHeaderCreated; 

        container                   statementLineCont; 

        boolean                     lineCreated;  

         

  

        while(!_asciFile.status()) 

        { 

            str firstColumn; 

  

            record = _asciFile.read(); 

             

            if(conLen(record)) 

            { 

                firstColumn = conPeek(record, 1); 

                firstColumn = strRem(firstColumn, '"\"'); 

  

                if(firstColumn == 'SH' && !bankStatementHeaderCreated) 

                { 

                    

                    statementFromdate = this.getDateTime(conPeek(record, 2), NoYes::Yes); 

                    statementTodate = this.getDateTime(conPeek(record, 3), NoYes::Yes); 

  

                    statement = this.insertIntoBankStmtISOHeader(statementFromdate, statementTodate, strRem(conPeek(record, 4), '"\"')); 

                    bankStmtISOHeaderRecid = statement.RecId; 

                    bankStatementHeaderCreated = true; 

                } 

                else if(firstColumn == 'SB') 

                { 

                    statementLineCont += [record]; 

                } 

            } 

        } 

        //insert statement lines 

        if(conLen(statementLineCont) && bankStatementHeaderCreated) 

        { 

            this.insertIntoP_bank_bankBankStmtISOReportEntry(bankStmtISOHeaderRecid, statem