Latest Microsoft Dynamics 365 Blogs | CloudFronts - Page 7

Reducing Try-Catch in Dynamics 365 Plugins Using DTO Validation Classes

Dynamics 365 plugins run inside an event-driven execution pipeline where business rules and data validation must be enforced before database operations complete. As systems evolve, plugin code often degrades into heavy defensive programming filled with null checks, type casting, and nested exception handling. Over time, exception handling begins to overshadow the actual business logic. This article introduces a DTO + Validation Layer pattern that restructures plugin design into a clean, testable, and scalable architecture. What Is “Try-Catch Hell” in Plugins? Typical Causes Symptoms Issue Impact Deep nested try-catch blocks Hard-to-read code Repeated attribute checks Code duplication Business logic hidden in error handling Difficult debugging Validation spread across plugins Inconsistent rules Result:Plugins behave like procedural error-handling scripts instead of structured business components. Architectural Shift: Entity-Centric → DTO-Centric Traditional plugins manipulate the CRM Entity directly. Problem:The Entity object is: This makes failures more likely. Proposed Flow This separates: DTO: A Strongly-Typed Contract DTOs act as a safe bridge between CRM data and business logic. Without DTO With DTO Dynamic attributes Strong typing Runtime failures Compile-time safety SDK-dependent logic Business-layer independenc Mapping Layer: Controlled Data Extraction All CRM attribute handling is isolated in one place. Benefits Validation Layer: Centralized Rule Logic Traditional DTO Validation Model Validation inside plugin Dedicated validator class Hard to reuse Reusable Hard to test Unit-test friendly The Clean Plugin Pattern Now the plugin: Reduction of Exception Noise Before: Exceptions for missing fields, null references, casting issues, and validation errors. After: Only meaningful business validation exceptions remain. The architecture shifts from reactive error handling to structured validation. Generative Design Advantages Capability Benefit New fields Update DTO + Mapper only New rules Extend validator Shared logic Reuse across plugins Automated testing No CRM dependency Testability Improvement No CRM context required. Performance Considerations To conclude, the DTO + Validation pattern is not just a coding improvement- it changes the way plugins are built. In many Dynamics 365 projects, plugins slowly become difficult to read because developers keep adding null checks, type conversions, and try-catch blocks. Over time, the actual business logic gets lost inside error handling. Using DTOs and a Validation layer fixes this problem in a structured way. Instead of working directly with the CRM Entity object everywhere, we first convert data into a clean, strongly typed DTO. This removes repeated attribute checks and reduces runtime errors. The code becomes clearer because we work with proper properties instead of dictionary-style field access. Then, all business rules are moved into a Validator class. This means: Now the plugin only performs four simple steps: Get data → Convert to DTO → Validate → Run business logic Because of this: Developers can understand the purpose of the plugin faster, instead of trying to follow complex nested try-catch blocks. If your Dynamics 365 environment is evolving in complexity, reach out to CloudFronts, transform@cloudfronts.com, specialists regularly design and implement structured plugin architectures that improve performance, maintainability, and long-term scalability.

Share Story :

How to Generate and Use SSL Certificates in Microsoft Dynamics 365 Business Central

Security is a critical aspect of any ERP implementation. When integrating Microsoft Dynamics 365 Business Central with external systems such as APIs, payment gateways, banks, IRIS, VAT systems, or third-party services, SSL/TLS certificates play a key role in securing communication. A common misconception is that Business Central itself generates SSL certificates. In reality, Business Central only consumes certificates-the generation and management are handled externally. In this blog, we will cover: What Is an SSL Certificate in Business Central? An SSL (Secure Sockets Layer) / TLS certificate is used to:\Hook: In Business Central, certificates are commonly used for: Important: Business Central does not create SSL certificates—it only stores and uses them. Steps to Generate an SSL Certificate (Self-Signed) This approach is typically used for development or on-premises environments. Step 1: Create a Self‑Signed Certificate in IIS Step 2: Provide Certificate Details Step 3: Copy the Certificate Thumbprint This thumbprint will be required in the next step. Step 4: Configure Certificate Using PowerShell Step 5: Verify Required Properties Ensure all required certificate properties are set to True, including: Step 6: Bind the Certificate in IIS Step 7: Add Certificate Using MMC Step 8: Verify Certificate Installation The certificate should now be visible under: Step 9: Grant Permissions to Business Central Service This ensures the Business Central service can access the certificate. To conclude, SSL certificates are a core security component in Business Central integrations. While Business Central does not generate certificates, it provides robust mechanisms to store and consume certificates securely in both cloud and on‑prem environments. Understanding the generation, configuration, and usage flow ensures secure, compliant, and reliable integrations. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Finding the Right Events in Business Central: Payment Journals & Purchase Orders

When working with Payment Journals in Microsoft Dynamics 365 Business Central, one of the most common customization requirements is to trigger custom logic immediately after the user selects the Applies-to Doc. No.. In one of my recent client projects, the requirement was very specific: As soon as a payment journal line is applied to an invoice (via Applies-to Doc. No. lookup), the system should automatically calculate amounts and create additional retained lines (VAT and IRIS). Sounds simple, right? The real challenge was finding the correct event that fires after the lookup completes and after Business Central internally updates the journal line fields. This blog documents: Problem Statement The client wanted the following behavior in Payment Journal: The logic must run right after the lookup, not during posting and not on page validation. Why Page Events Were Not Enough Initially, it is natural to look for: However, in this case: So even though the value was visible, the amounts were not reliable yet. Using Event Recorder to Find the Right Event This is where Event Recorder becomes extremely powerful. Steps I Followed The recorder captured a detailed list of: After analyzing the sequence, one event stood out. The Key Event That Solved the Problem The event that fulfilled the exact requirement was: [EventSubscriber(    ObjectType::Table,    Database::”Gen. Journal Line”,    ‘OnLookupAppliestoDocNoOnAfterSetJournalLineFieldsFromApplication’,    ”,    false,    false)]local procedure OnAfterLookupAppliesToDocNo(var GenJournalLine: Record “Gen. Journal Line”) Why This Event Is Perfect This is exactly the moment where custom business logic should run. Implementing the Business Logic Below is the simplified version of the logic implemented inside the subscriber: local procedure OnAfterLookupAppliesToDocNo(var GenJournalLine: Record “Gen. Journal Line”)begin    GenJournalLine.GetUpdatedAmount(); if GenJournalLine.”Applies-to Doc. No.” <> ” then begin        GenJournalLine.GetUpdatedAmount_(GenJournalLine);        AppliestoDocNo := GenJournalLine.”Applies-to Doc. No.”;        GenJournalLine.CreateRetainedVATLine(GenJournalLine, AppliestoDocNo);        GenJournalLine.CreateRetainedIRISLine(GenJournalLine, AppliestoDocNo);    end;end; What This Code Does All of this happens immediately after the lookup, without waiting for posting. Important Design Notes Key Takeaway Finding the right event is often harder than writing the logic itself. In scenarios where: This table event: OnLookupAppliestoDocNoOnAfterSetJournalLineFieldsFromApplication is a hidden gem for Payment Journal customizations involving Applies-to logic. Another Real-World Case: Invoice Discount Recalculation on Purchase Orders In the same project, we faced another tricky requirement related to Invoice Discounts on Purchase Orders. The Problem did not fire reliably when invoice discounts were recalculated by the system This became an issue because the client wanted custom tax and withholding logic (IR, IS, Withheld VAT, Excise) to be recalculated immediately after invoice discount recalculation. Why Page and Line Events Failed Again Business Central recalculates invoice discounts using an internal codeunit: Purch – Calc Disc. By Type This logic: So once again, page-level and line-level events were too early or never triggered. Finding the Right Event (Again) Using Event Recorder Using Event Recorder, I traced the execution when: This led to the discovery of another perfectly-timed system event. The Key Event for Invoice Discount Scenarios [EventSubscriber(    ObjectType::Codeunit,    Codeunit::”Purch – Calc Disc. By Type”,    ‘OnAfterResetRecalculateInvoiceDisc’,    ”,    false,    false)]local procedure OnAfterResetRecalculateInvoiceDisc(var PurchaseHeader: Record “Purchase Header”) Why This Event Works Applying Custom Logic on Purchase Lines local procedure OnAfterResetRecalculateInvoiceDisc(var PurchaseHeader: Record “Purchase Header”)var    PurchLine: Record “Purchase Line”;begin    PurchLine.SetRange(“Document Type”, PurchaseHeader.”Document Type”);    PurchLine.SetRange(“Document No.”, PurchaseHeader.”No.”); if PurchLine.FindSet() then        repeat            PurchLine.UpdateIRandIS();            PurchLine.CalculateWithHeldVAT();            PurchLine.CalculateIR();            PurchLine.CalculateIS();            PurchLine.CalculateExcise(); PurchLine.Modify();        until PurchLine.Next() = 0;end; What Happens Here All of this happens automatically, without relying on UI triggers. Key Lessons from Both Scenarios Final Thoughts Both of these scenarios reinforce one important principle in Business Central development: Finding the right event matters more than writing the logic itself. Whether it is: The solution lies in understanding where Business Central actually performs the work – and subscribing after that point. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Create records in Dynamics CRM using Microsoft Excel Online

Quick Preview Importing customer data into Dynamics 365 can be simple and efficient. Whether you’re transitioning from another system or adding a large batch of new customers, Microsoft Excel Online offers a practical way to create multiple records at once—without any technical configuration. In this blog, I’ll walk you through a clear, step-by-step approach to importing customer (or any entity) records directly into your Dynamics 365 environment using Excel Online. By the end, you’ll be able to upload bulk data quickly while maintaining accuracy and data consistency. Let’s get started and see how you can seamlessly import multiple customer records into Dynamics 365 using Excel Online. Step 1: Go to the entity’s home page who’s records you want to create (In my case it is customer entity).   Step 2: On the active accounts view (or any view) click on edit columns and add the columns as per the data you want to be fill in. (Don’t forget to hit apply button at the bottom)  Step 2 : Once your view is ready click on Export to Excel Button on the top left and select Open in excel online.  Step 3: If you are using a system view like in this example you will see existing records on the online excel, you can clear those records or keep them as is. If you change any existing record, it will update the data of that record so you can also use this to update existing records at once (I will write a separate blog post for updating records for now let’s focus on creating records)  Step 4: You can then add the data which you want to create to the online excel sheet, in this example I am transferring data from a local excel sheet to the online excel.  Step 5: Once you have added your data on the online excel, hit apply button.  Step 6: You will get a Popup about your data being submitted for import, hit Track Progress.  Step 7: You will see your data has been submitted and is parsing. (It will take couple of minutes to hours depending upon the amount of data you have submitted keep refreshing to see the progress of the records).  Step 8: Once the import job is completed you will see how many records were created successfully and how many failed or partially failed. You can open the import job and check failed entries, correct the entries and re-import   Failed records  All the successfully parsed records will be created in your system.  Importing customer records in Dynamics 365 becomes incredibly seamless with Excel Online. With just a few steps-preparing your view, exporting to Excel, adding your data, and submitting the import-you can create hundreds or even thousands of records in a fraction of the time. This approach not only speeds up data entry but also ensures consistency and reduces manual errors. Hope this helps! 😊  I Hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudFronts.com.

Share Story :

SMTP with OAuth 2.0 in Business Central: A Modern Email Setup

Email remains one of the most critical communication tools in Business Central. Whether you’re sending invoices, notifications, or workflow approvals, the reliability and security of your email integration matter. With Microsoft officially retiring Basic Authentication in Exchange Online, Business Central users must now embrace OAuth 2.0 for SMTP connections. Let’s explore what this means and how to configure it. Why the Shift to OAuth 2.0? Setting Up SMTP with OAuth 2.0 in Business Central The process is simpler than many expect. Here’s the streamlined approach: To conclude, switching to SMTP with OAuth 2.0 in Business Central is not just a technical requirement it’s a strategic move toward secure, modern communication. The setup is straightforward, but the payoff is significant: stronger security, smoother compliance, and reliable email delivery.

Share Story :

Secure Email Setup in Dynamics 365 Finance & Operations with SMTP

Email remains a vital communication tool in Dynamics 365 Finance & Operations, powering workflows like invoice delivery, notifications, and approvals. To ensure secure and reliable email transmission, organizations configure SMTP directly within F&O. This guide walks through the streamlined steps to configure SMTP in F&O so your system can send emails seamlessly. Steps to Achieve goal 2. Go to SMTP settings and enter below valuesEnter SMTP Server Details Enable SSL/TLS if required. Server: e.g., smtp.office365.com Port: usually 587 (TLS) 3. Define Sender Address Ensure each user has a valid email address in User options → Email. To conclude, configuring SMTP in Dynamics 365 F&O is a straightforward process that unlocks secure and efficient email communication across your business processes. By entering the correct server details, authentication method, and sender information, you enable F&O to deliver messages reliably without manual intervention. With SMTP in place, Finance & Operations becomes not just a system of record, but a system of communication. We hope you found this article useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Implementing Custom Auto Numbering in Dynamics 365 CRM

In Microsoft Dynamics 365 CRM, every Case (Incident) record comes with a default Ticket Number. Microsoft generates it automatically, and while that’s fine for basic tracking, it usually doesn’t survive first contact with real business requirements. Users want meaningful Case IDs—something that actually tells them what kind of case this is, what service it belongs to, and where it came from. Unfortunately, since Ticket Number (ticketnumber) is a Microsoft-managed field, you can’t just slap a custom format on it using configuration alone. That’s exactly where a Pre-Operation plugin comes in. This blog walks through a real production use case where we customize the default Case ID format without breaking Microsoft’s auto-numbering, and without creating race conditions or duplicate numbers. Use Case Table: Case (Incident) Field: Ticket Number (ticketnumber) Requirement: Execution: Why Pre-Operation Microsoft generates the Ticket Number before the Create operation completes. In Pre-Operation, we can: This gives us: The Custom Ticket Number Format The final Case ID looks like this: Example: Plugin Logic Overview Here’s what the plugin does, step by step: The Plugin Code Plugin Registration Details Message: Create Primary Entity: Case (incident) Stage: Pre-Operation Mode: Synchronous Filtering Attributes: Not required. To conclude, customizing a Microsoft-managed field like Ticket Number often sounds risky, but as you’ve seen, it doesn’t have to be. By letting Dynamics 365 generate the number first and then reshaping it in a pre-Operation plugin, you get the best of both worlds. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Scaling Customer Support: Implementing Service Request Management with Dynamics 365

Summary For growing businesses, service request management becomes crucial as volume and complexity increase. Email-driven support and Excel trackers often fail to scale effectively. A structured Service Request Management System (SRMS) centralizes tracking, automates processes, and enforces SLAs. Microsoft Dynamics 365 Customer Service enables operational, accountable support management. Implementing the right system ensures efficiency, transparency, and customer satisfaction as businesses grow. Table of Contents 1. Key Components of an SRMS 2. Setting Up Service Request Management 3. Operationalizing with Dynamics 365 4. Customer Success Story Key Components of a Service Request Management System For growing businesses, as much as their processes, reports, and efficient systems are important, service request management becomes equally crucial. As companies scale, the volume and complexity of service requests increase, making efficient management essential to maintaining operational flow and customer satisfaction. A well-designed Service Request Management System (SRMS) helps align workflows, reduce response times, and enhance service delivery. Centralized Request Tracking: A centralized service request management system (SRMS) allows businesses to log, track, and manage all service requests in one place. Unified Dashboard: A centralized dashboard provides a comprehensive view of all service requests, their statuses, and assigned personnel. Prioritization and Categorization: Service requests can be categorized and prioritized based on urgency, impact, and type. Automatic Case Creation and Update Rule: Automation features such as automatic ticket creation, escalation rules, and status updates help reduce manual effort. Service Level Agreements (SLAs): SLAs define expected response and resolution times and ensure deadlines are met. Automated Assignment: Service requests are automatically assigned based on expertise, workload, and availability. Real-Time Updates: Service agents update request statuses in real time, providing accurate information to stakeholders. Customer Self-Service Portal: Customers can submit and track service requests independently. Setting Up Service Request Management for a Growing Business Support Email Address: Customers send queries to support@companydomain.com. Automatic Case Creation: Requests sent to the support email are automatically converted into cases. Case Assignment: Once a case is created, it is assigned to a support team member. Acknowledgment Emails: A confirmation email is sent to the customer. Team Notification: The assigned team member receives a notification. Progress Updates: Team members add notes and updates to the ticket. Real-Time Updates: Updates are sent to the customer via email in real time. Defaulter Report: A defaulter report is generated internally to manage SLA breaches. Case Closure Notifications: Notifications are sent to customers upon cancellation or resolution. Email Tracking: All communication via email is automatically tracked by the system. Service Request Management Portal: A portal can be provided to selected customers for managing service requests. Operationalizing Customer Service with Dynamics 365 If your customer support still lives in shared inboxes and Excel trackers, you’re not alone. As volumes increase, this setup quickly turns into missed SLAs, inconsistent updates, and frustrated customers. Automatic case creation from support emails, portals, or web forms Queue-based assignment End-to-end tracking of customer interactions Business Process Flows (Identify → Research → Resolve) SLA-driven reminders and alerts One-click email responses from the case record Self-service portal support Watch the Full Webinar Demo To see how Dynamics 365 Customer Service operationalizes service management in real time, watch the complete webinar session below: Frequently Asked Questions Why does email-only support fail at scale? It lacks centralized tracking, SLA enforcement, ownership clarity, and structured workflows. What is the main benefit of an SRMS? Centralized visibility, automation, and accountability. Can customers continue using email? Yes. Emails are automatically converted into tracked cases internally. Customer Success Story Having a solid service request management system (SRMS) is a game-changer for any growing business. By centralizing service requests, automating processes, and setting clear expectations with SLAs, businesses can maintain efficiency and customer satisfaction as they grow. Here is our featured Customer Success Story: Revolution Cooking partnered with CloudFronts for Dynamics 365 enhancements and data integration with third-party applications.

Share Story :

Opening an HTML Web Resource from a Subgrid Button in Dynamics 365 CRM

Posted On February 12, 2026 by Admin Posted in

An Australia-based linen manufacturing and distribution company was using Microsoft Dynamics 365 to manage their sales lifecycle. Their sales process included: The issue arose when sales representatives needed to add multiple existing products to an Opportunity. The Real Problem Out-of-the-box behavior in Dynamics 365 allows users to: While this works functionally, it becomes inefficient for organizations managing: This resulted in: The business requirement was clear: Users should be able to select multiple existing products and create Opportunity Product records in bulk, from a single interface. Architectural Decision Instead of: To address this, we introduced a custom button on the Opportunity Products subgrid. When clicked, it opens an HTML web resource that allows users to select multiple existing products in a single interface. The selected products are then processed through a Custom Action, which handles the bulk creation of Opportunity Product records server-side. Why Use an HTML Web Resource? In Microsoft Dataverse, not every customization belongs directly inside the main form. Sometimes we need: HTML Web Resources allow us to build: Without disturbing the standard CRM experience. The Web Resource We created an HTML web resource named: The HTML web resource renders a searchable grid of existing Product records, allowing users to perform multi-selection. The selected product IDs are then passed to a Custom Action, which handles the creation of related Opportunity Product records against the active Opportunity. Opening the HTML Web Resource from the Subgrid Button The key technical step was opening the HTML page when the custom ribbon button is clicked. We used modern navigation APIs. JavaScript Used on the Ribbon Button How This Works When the custom button is clicked, the script first retrieves the current Opportunity record ID. This ID is then passed as a parameter to the HTML web resource so that the selected products can be associated with the correct Opportunity. The web resource is opened as a modal dialog using the target: 2 navigation option, ensuring that users can complete the bulk selection process without leaving the form. Inside the HTML Web Resource Within the HTML web resource: This design ensures: All without navigating away from the form. How This Approach Saved Time Faster User Workflow Users select multiple products in one screen. Clean Architecture Concern Where It Lives Business Data Dataverse UI Interaction HTML Web Resource Batch Logic Custom Action (C# Plugin) To encapsulate, with this design the Client was able to: Opening an HTML Web Resource from a button in Microsoft Dynamics 365 is a powerful extension technique. It allows organizations to: We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Implementing Plugin for Automated Lead Creation in Dynamics 365

Dynamics 365 CRM plugins are a powerful way to enforce business logic on the server but choosing when and how to use them is just as important as writing the code itself. In one implementation for a Netherlands-based sustainability certification organization, the client needed their certification journey to begin with a custom application entity while still ensuring that applicant and company details were captured as leads for downstream sales and engagement processes. This blog explores how a server-side plugin was used to bridge that gap, reliably creating and associating lead records at runtime while keeping the solution independent of UI behavior and future integrations. In this scenario, the certification application was the starting point of the business process, but sales and engagement still needed to operate on leads. Simply storing the same information in one place wasn’t enough, the system needed a reliable way to translate an application into a lead at the right moment, every time. That transformation logic is neither data storage nor UI behavior; its core business process logic, which is why it was implemented using a Dynamics 365 plugin. Scenario: Certification Application Not Flowing into Sales Users reported the following challenge: a. A user submits or creates a Certification Applicationb. Applicant and company details are captured on a custom entityc. Sales teams expect a Lead to be created for follow-upd. No Lead exists unless created manually or through inconsistent automatione. Application and sales data become disconnected This breaks the intended business flow, as certification teams and sales teams end up working in parallel systems without a reliable link between applications and leads. Possible Solution: Handling Lead Creation Through Manual Processes (Original Approach) Before implementing the plugin, the organization attempted to manage lead creation manually or through disconnected automation. How It Worked (Initially) a. A Certification Application was submittedb. Users reviewed the applicationc. Sales team manually created a Lead with applicant/company detailsd. They tried to match accounts/contacts manuallye. Both records remained loosely connected. Why This Might Look Reasonable a. Simple to explain operationallyb. No development effortc. Works as long as users follow the steps perfectly The Hidden Problems 1] Inconsistent Data Entry a. Users forgot to create leadsb. Leads were created with missing fieldsc. Duplicate accounts/contacts were createdd. Sales lost visibility into new certification inquiries 2] Broken Cross-Department Workflow a. Certification team worked in the custom entityb. Sales team worked in Leadsc. No structural linkage existed between the twod. Downstream reporting (pipeline, conversion, source tracking) became unreliable. Workaround to This Approach: Use Server-Side Logic Instead of Manual Steps Practically, the transformation of an application into a lead is business logic, not user behavior. Once that boundary is respected, the solution becomes stable, predictable, and automation-friendly. Practical Solution: A Server-Side Plugin (Improved Approach) Instead of depending on people or scattered automation, the lead is created centrally and automatically through a plugin registered on the Certification Application entity. Why a Plugin? a. Executes consistently regardless of data sourceb. Not tied to form events or UI interactionsc. Can safely check for existing accounts/contactsd. Ensures one source of truth for lead and application linkagee. Works for portal submissions, integrations, and bulk imports This is essential for a client, where applications may originate from multiple channels and must feed accurately into the sales funnel. How the Plugin-Based Solution Works The solution was implemented using a server-side plugin registered on the Certification Application entity. The plugin executes when a new application is created, retrieves the necessary applicant and organization details, performs basic checks for existing accounts and contacts, creates a Lead using the extracted data, and finally links the Lead back to the originating application record. This ensures that every certification application automatically enters the sales pipeline in a consistent and reliable manner. Implementation Steps (For Developers New to Plugins) If you’re new to Dynamics 365 plugins, the implementation followed these core steps: Build and Register the Plugin. Once the plugin logic is implemented, build the project to generate the signed assembly. After a successful build: After registration, every new Certification Application will automatically trigger the plugin, ensuring that a Lead is created and linked without any manual intervention. a. Open the Plugin Registration Toolb. Connect to the target Dynamics 365 environmentc. Register the compiled assemblyd. Register the plugin step on the Create message of the Certification Application entitye. Configure the execution stage (typically post-operation) and execution mode (Synchronous or Asynchronous, depending on business needs) To encapsulate, this solution shows why server-side plugins are the right place for core business logic in Dynamics 365. By automatically creating and linking a Lead when a Certification Application is created, the organization removed manual steps, prevented data inconsistencies, and ensured that every application reliably flowed into the sales pipeline. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

SEARCH BLOGS:

FOLLOW CLOUDFRONTS BLOG :


Categories

Secured By miniOrange