Custom Folder Logic
This page provides guidance on implementing custom folder structures and logic beyond the standard mapping options.
When Custom Logic is Needed
Standard Mapping Limitations
Standard mapping handles most scenarios, but custom logic may be needed for:
| Scenario | Why Custom |
|---|---|
| Calculated folder names | Year from date, fiscal period |
| Complex conditions | Multiple field combinations |
| Dynamic routing | Runtime decisions |
| Integration requirements | External system data |
Examples Requiring Custom Logic
- Year folders from Posting Date (e.g.,
/Invoices/2024/) - Fiscal year based on custom calendar
- Region determined by multiple fields
- Customer tier from external calculation
Customization Approaches
Event Subscribers
The connector may expose events for customization:
- Before folder creation
- Before upload
- After matching
- Custom metadata
Code Extensions
Extend connector codeunits to modify behavior:
- Override folder path logic
- Add custom validations
- Modify file naming
Folder Path Customization
Concept
Custom folder logic modifies how the destination path is determined:
Standard: /Customers/{Customer.Name}
Custom: /Customers/{Customer.Name}/{Year(PostingDate)}
Implementation Pattern
// Conceptual pattern - actual implementation depends on connector events
[EventSubscriber(ObjectType::Codeunit, Codeunit::"SharePoint Integration", 'OnBeforeGetFolderPath', '', false, false)]
local procedure CustomizeFolderPath(TableNo: Integer; RecRef: RecordRef; var FolderPath: Text)
var
SalesInvHeader: Record "Sales Invoice Header";
begin
if TableNo = Database::"Sales Invoice Header" then begin
RecRef.SetTable(SalesInvHeader);
FolderPath := FolderPath + '/' + Format(Date2DMY(SalesInvHeader."Posting Date", 3));
end;
end;
Year-Based Folders
Common Requirement
Organize documents by year:
/Customers/Contoso/
├── 2023/
│ └── (2023 documents)
├── 2024/
│ └── (2024 documents)
└── 2025/
└── (2025 documents)
Implementation Considerations
| Consideration | Note |
|---|---|
| Which date field? | Posting Date, Document Date, etc. |
| Format | 2024, 24, FY2024, etc. |
| Fiscal year | May differ from calendar |
Fiscal Year Logic
For fiscal years not matching calendar:
local procedure GetFiscalYear(PostingDate: Date): Text
var
AccountingPeriod: Record "Accounting Period";
begin
AccountingPeriod.SetRange("New Fiscal Year", true);
AccountingPeriod.SetFilter("Starting Date", '<=%1', PostingDate);
if AccountingPeriod.FindLast() then
exit(Format(Date2DMY(AccountingPeriod."Starting Date", 3)));
exit(Format(Date2DMY(PostingDate, 3)));
end;
Complex Conditions
Multi-Field Conditions
When routing depends on multiple fields:
local procedure GetCustomFolder(Customer: Record Customer): Text
begin
case true of
Customer."Country/Region Code" in ['US', 'CA', 'MX']:
exit('Americas');
Customer."Country/Region Code" in ['DE', 'FR', 'GB', 'IT']:
exit('Europe');
else
exit('Other');
end;
end;
Combining Conditions
Layer multiple conditions:
Base: /Documents
+ Region: /Americas
+ Year: /2024
+ Type: /Invoices
= /Documents/Americas/2024/Invoices/
Metadata-Driven Routing
Using External Data
Route based on data from other sources:
- Master data attributes
- Configuration tables
- External systems
Example Pattern
local procedure GetRoutingFromConfig(TableNo: Integer; RecordId: Text): Text
var
RoutingConfig: Record "My Routing Config";
begin
if RoutingConfig.Get(TableNo, RecordId) then
exit(RoutingConfig."Folder Path");
exit('');
end;
Integration Patterns
VerifyAccess Pattern
For long-running operations, maintain token validity:
// Before each batch of operations
procedure EnsureAccess()
var
SharePointEFQ: Codeunit "SharePoint EFQ";
begin
SharePointEFQ.VerifyAccess();
// Refresh token if needed
// This prevents expiration during long processes
end;
Error Handling
Implement robust error handling:
local procedure SafeCreateFolder(Path: Text): Boolean
begin
// Attempt creation
// Handle specific errors
// Return success/failure
end;
Testing Custom Logic
Test Scenarios
| Test | Verify |
|---|---|
| Standard records | Custom logic doesn't break standard |
| Edge cases | Handles unusual data |
| Error conditions | Graceful failures |
| Performance | Acceptable speed |
Testing Approach
- Unit test custom procedures
- Integration test with connector
- End-to-end test with SharePoint
- Performance test with volume
Documentation
Document Your Customizations
Record:
| Item | Why |
|---|---|
| What was customized | Future reference |
| Why | Business requirement |
| How it works | Maintenance |
| Test cases | Verification |
Maintenance Considerations
Custom logic requires:
- Updates when connector updates
- Testing after BC upgrades
- Documentation for support
Best Practices
Code Quality
| Practice | Benefit |
|---|---|
| Clear naming | Understandable code |
| Comments | Explain why, not what |
| Error handling | Robust operation |
| Logging | Troubleshooting |
Upgrade Safety
| Practice | Benefit |
|---|---|
| Use events when available | Less coupling |
| Isolate custom code | Easier updates |
| Test after upgrades | Catch issues |
Getting Help
Development Support
For custom development:
- Contact the publisher for guidance
- Engage a development partner
- Review available events/interfaces
Documentation Resources
- Publisher API documentation (if available)
- BC development documentation
- Community forums