CRM - [File Upload/Report changes]

CRM - [File Upload/Report changes]

Doubts

  1. Upload
  • Do we need to show any field on the page?
  • Do we need to hide the upload link based on date like Invoice
  • It is taking some time to load page
  • Extension logic needs to be discussed.
  • Getting warning

Report Changes

  • Need to add columns preaging and postaging in Aging sheet instead of Aging Column
public class CrmLeadSummaryReport
{
    // public int AgingDays { get; set; }
    public int PreAgingDays { get; set; }
    public int PostAgingDays { get; set; }
}
  • Query Changes
var agingQuery = @"WITH A (LeadNo) AS
(
    SELECT DISTINCT LeadNo
    FROM CrmLead1
    WHERE Dated BETWEEN @FromDate AND @ToDate
),
B (LeadNo, MinDate, MaxDate) AS
(
    SELECT A.leadno, 
    MIN(L1.Dated) AS MinDate,
    MAX(L1.Dated) AS MaxDate
    FROM A
    LEFT JOIN CrmLead1 L1 ON A.leadno = L1.leadno
    GROUP BY A.leadno
)
SELECT L.LeadNo,L.LeadName,SM.smname AS SalesmenName,L.ContactName,
IIF(L.LeadStatus = 'E', 'Engaged',
IIF(L.LeadStatus = 'C', 'Converted',
IIF(L.LeadStatus = 'D', 'Dropped', L.LeadStatus))) AS LeadStatusName,
B.MinDate AS LeadCreatedDate,B.MaxDate AS LastActivityDate,
DATEDIFF(DAY, B.MinDate, B.MaxDate) AS PreAgingDays,
DATEDIFF(DAY, B.MaxDate, GETDATE()) AS PostAgingDays
FROM B
LEFT JOIN CrmLead L ON B.LeadNo = L.LeadNo
LEFT JOIN Salesmen SM ON L.SalesmenCode = SM.smno
ORDER BY PreAgingDays DESC, PostAgingDays DESC, L.LeadNo";

Upload Feature

  • Add upload, download, reupload feature in CrmLead1.
  • Upload razor Page
@page "/crmlead1upload/{id}"

@inject ICrmLeadService _ICrmLeadService

<MudText Typo="Typo.h4">Upload Document</MudText>

<EditForm Model="@_CrmLead1">
    <MudGrid>
        <MudItem xs="12" sm="7">
            <MudCard>
                <MudCardContent>
                    <MudFileUpload T="IBrowserFile" For="@(() => uploadedFile)" @bind-Files="uploadedFile"
                        Accept=".pdf,.xlsx,.png,.docx">
                        <ButtonTemplate Context="filecontext">
                        <MudButton HtmlTag="label" Variant="Variant.Filled" Color="Color.Tertiary"
                            StartIcon="@Icons.Material.Filled.AttachFile" for="@filecontext">
                            Select File
                        </MudButton>
                        </ButtonTemplate>
                        <SelectedTemplate Context="filecontext">
                            @if (filecontext != null)
                            {
                                <MudText>@filecontext.Name</MudText>
                            }
                            else
                            {
                                <MudText>No File</MudText>
                            }
                        </SelectedTemplate>
                    </MudFileUpload>

                </MudCardContent>
                <MudCardActions>
                    <MudStack Row="true">
                        <MudButton OnClick="CrmLead1UploadPage" Variant="Variant.Filled" Color="Color.Primary"
                        Class="ml-auto" StartIcon="@Icons.Material.Filled.CloudUpload">Upload</MudButton>
                       <MudButton Variant="Variant.Filled" Color="Color.Default" OnClick="Back"
                        StartIcon="@Icons.Material.Filled.ArrowBack">Back</MudButton>
                    </MudStack>
                </MudCardActions>
            </MudCard>
        </MudItem>
    </MudGrid>
</EditForm>

@code {

    CrmLead1 _CrmLead1 = new ();
    [Parameter]
    public string id { get; set; } = string.Empty;
    PostLogin _PostLogin = new ();
    IBrowserFile? uploadedFile;
    public bool isProcessing;

    protected override async Task OnInitializedAsync()
    {
        _PostLogin = await _LocalSession.GetItemAsync<PostLogin>("userinfo");

        var rolecnt = _IPostLoginService.GetUserRolesCnt(_PostLogin.userdb, "CrmLeadCreate", _PostLogin.dbname);
        var usersessionid = _IPostLoginService.GetUserSessionId(_PostLogin.userdb);
        usersessionid = usersessionid.Replace("\"","");
                
        if(_PostLogin.BrowserSessionId != usersessionid)
        {
            NavManager.NavigateTo("/invaliduser/5");
        }
        else if(rolecnt == 0)
        {
            NavManager.NavigateTo("/accessdenied/1");
        }
        else
        {
           _CrmLead1 = await _ICrmLeadService.CrmLead1Details(Convert.ToInt32(id), _PostLogin.dbname);
        }
    }

    private async void CrmLead1UploadPage()
    {
        var maxFileSize = 1000000;
        if (uploadedFile == null)
        {
            _ISnackbar.Add("File needs to be selected.", Severity.Error);
        }
        else if (uploadedFile.Size > maxFileSize)
        {
            _ISnackbar.Add("File size must be up to 1 MB", Severity.Error);
        }
        else
        {
            isProcessing = true;
            using var stream = uploadedFile.OpenReadStream(maxFileSize);
            var extension = Path.GetExtension(uploadedFile.Name);
            var key = $"MFGReports/Docs/{_PostLogin.dbname}/CRM Lead/{_CrmLead1.LeadNo}{_CrmLead1.Id}{extension}";

            var request = new Amazon.S3.Model.GetPreSignedUrlRequest
            {
                BucketName = _bucketName,
                Key = key,
                Verb = Amazon.S3.HttpVerb.PUT,
                Expires = DateTime.UtcNow.AddMinutes(5),
                ContentType = $"application/{extension}"
            };

            var preSignedUrl = _s3Client!.GetPreSignedURL(request);

            using var memoryStream = new MemoryStream();
            await stream.CopyToAsync(memoryStream);

            memoryStream.Position = 0;

            using var content = new StreamContent(memoryStream);
            content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue($"application/{extension}");
            content.Headers.ContentLength = memoryStream.Length;

            var uploadResponse = await _IUtilityMethodsService.UploadS3File(preSignedUrl, content);

            if (uploadResponse.IsSuccessStatusCode)
            {
                _ISnackbar.Add($"Document is uploaded Successfully.", Severity.Success);         
                NavManager.NavigateTo($"/crmlead1details/{Convert.ToInt32(id)}");          
            }
            else
            {
                _ISnackbar.Add($"Upload failed. Please try again later.", Severity.Error);
            }

            isProcessing = false;
            StateHasChanged();
        }
    }

    public void Back() => NavManager.NavigateTo($"/crmlead1details/{Convert.ToInt32(id)}");
}
  • In details1 need to give upload, download, reupload button.
@if(fileExists == false)
{
    <tr>
    <th>Upload Document</th>
    <td>
        <MudLink Href=@($"crmlead1upload/{Convert.ToInt32(id)}") Variant="Variant.Text" 
            Color="Color.Primary">Upload Document</MudLink>
    </td>
    </tr>
}
else if (fileExists == true)
{
    <tr>
        <th>Re-Upload / Download Document </th> 
        <td>
            <MudStack Row="true">
                <MudLink Href=@($"crmlead1upload/{Convert.ToInt32(id)}") Variant="Variant.Text" 
                    Color="Color.Primary">Re-Upload Document</MudLink>
                <MudLink OnClick="@DownloadDocument" Variant="Variant.Text" 
                    Color="Color.Primary">Download</MudLink>
            </MudStack>
        </td>
    </tr>
}


/// On OnInitializedAsync
var prefix = $"MFGReports/Docs/{_PostLogin.dbname}/CRM Lead/{_CrmLead1.LeadNo}{_CrmLead1.Id}";

var response = await _s3Client.ListObjectsV2Async(new ListObjectsV2Request
{
    BucketName = _bucketName,
    Prefix = prefix,
    MaxKeys = 1
});

if (response.S3Objects != null)
{
    var s3Object = response.S3Objects.FirstOrDefault();

    fileExists = s3Object != null;
    extension = fileExists ? Path.GetExtension(s3Object.Key) : null;
}
  • Download Document Method
public void DownloadDocument()
{
    var randomFileName = $"{_CrmLead1.LeadNo}{_CrmLead1.Id}{extension}";
    var userFileName = $"Lead_{_CrmLead1.LeadNo}{_CrmLead1.Id}{extension}";
    var subFolderName = "CRM Lead";
    NavManager.NavigateTo($"filedownloader/s3downloadfile/{randomFileName}/{userFileName}/{_PostLogin.dbname}/{subFolderName}", true);
}
  • Delete1 Method Changes
var s3Key = $"MFGReports/Docs/{_PostLogin.dbname}/CRM Lead/{_CrmLead1.LeadNo}{_CrmLead1.Id}{extension}";

// 2. DELETE FILE IF IT EXISTS
if (fileExists)
{
    await _s3Client.DeleteObjectAsync(new DeleteObjectRequest
    {
        BucketName = _bucketName,
        Key = s3Key
    });
}