saas-management

star 1

نظام إدارة اشتراكات البرمجيات كخدمة (SaaS) والتراخيص. استخدم هذا الـ skill عند: إدارة اشتراكات SaaS، تتبع التراخيص، إدارة التكاليف، مراقبة الاستخدام، تجديد الاشتراكات، إدارة المستخدمين، تقييم الموردين، أو أي مهمة تتعلق بإدارة البرمجيات والخدمات السحابية والتراخيص.

mtatwercom By mtatwercom schedule Updated 2/14/2026

name: saas-management description: > نظام إدارة اشتراكات البرمجيات كخدمة (SaaS) والتراخيص. استخدم هذا الـ skill عند: إدارة اشتراكات SaaS، تتبع التراخيص، إدارة التكاليف، مراقبة الاستخدام، تجديد الاشتراكات، إدارة المستخدمين، تقييم الموردين، أو أي مهمة تتعلق بإدارة البرمجيات والخدمات السحابية والتراخيص.

SaaS & License Management

إدارة الاشتراكات والتراخيص

Domain Model

public class SaasSubscription : BaseAuditableEntity
{
    public int Id { get; set; }
    public string SubscriptionCode { get; set; } = string.Empty;
    public string ServiceNameAr { get; set; } = string.Empty;
    public string ServiceNameEn { get; set; } = string.Empty;
    public string ProviderName { get; set; } = string.Empty;
    public string? ProviderWebsite { get; set; }
    
    // Subscription Details
    public SaasCategory Category { get; set; }
    public string PlanName { get; set; } = string.Empty;
    public BillingCycle BillingCycle { get; set; }
    public decimal MonthlyCost { get; set; }
    public decimal AnnualCost { get; set; }
    public string Currency { get; set; } = "SAR";
    
    // License
    public int TotalLicenses { get; set; }
    public int UsedLicenses { get; set; }
    public int AvailableLicenses => TotalLicenses - UsedLicenses;
    public decimal CostPerLicense => TotalLicenses > 0 ? MonthlyCost / TotalLicenses : 0;
    public LicenseType LicenseType { get; set; }
    
    // Dates
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public DateTime? NextRenewalDate { get; set; }
    public bool AutoRenew { get; set; }
    public int RenewalNoticeDays { get; set; } = 30;
    
    // Status
    public SubscriptionStatus Status { get; set; }
    public int OwnerDepartmentId { get; set; }
    public int OwnerEmployeeId { get; set; }
    
    // Contract
    public int? ContractId { get; set; }
    public int? PurchaseOrderId { get; set; }
    public int? BudgetLineId { get; set; }
    
    // Security
    public DataResidency DataResidency { get; set; }
    public bool HasSSOIntegration { get; set; }
    public bool IsGovernmentCertified { get; set; }
    public string? SecurityCertifications { get; set; }
    
    public List<SaasUser> Users { get; set; } = new();
    public List<SaasUsageLog> UsageLogs { get; set; } = new();
}

public enum SaasCategory
{
    Productivity,       // إنتاجية (Office 365, Google Workspace)
    Communication,      // اتصالات (Teams, Zoom, Slack)
    ProjectManagement,  // إدارة مشاريع (Jira, Asana)
    CRM,                // إدارة علاقات العملاء
    HRM,                // موارد بشرية
    Finance,            // مالية ومحاسبية
    Security,           // أمن معلومات
    Development,        // تطوير برمجيات
    Design,             // تصميم
    Analytics,          // تحليلات
    CloudInfra,         // بنية تحتية سحابية
    Other               // أخرى
}

public enum DataResidency
{
    SaudiArabia,        // داخل المملكة
    GCC,                // دول الخليج
    MiddleEast,         // الشرق الأوسط
    International       // دولي
}

// === استخدام المستخدمين ===
public class SaasUser
{
    public int Id { get; set; }
    public int SubscriptionId { get; set; }
    public int EmployeeId { get; set; }
    public string? ExternalUserId { get; set; }
    public string Role { get; set; } = "user";
    public DateTime AssignedDate { get; set; }
    public DateTime? LastActiveDate { get; set; }
    public bool IsActive { get; set; } = true;
    public decimal MonthlyUsageHours { get; set; }
}

Cost Optimization Service

public class SaasOptimizationService
{
    public async Task<OptimizationReport> AnalyzeAsync()
    {
        var report = new OptimizationReport();
        
        // 1. Unused licenses
        var subscriptions = await _context.SaasSubscriptions
            .Include(s => s.Users)
            .Where(s => s.Status == SubscriptionStatus.Active)
            .ToListAsync();

        foreach (var sub in subscriptions)
        {
            var unusedLicenses = sub.TotalLicenses - sub.UsedLicenses;
            if (unusedLicenses > 0)
            {
                report.UnusedLicenses.Add(new()
                {
                    Subscription = sub.ServiceNameAr,
                    UnusedCount = unusedLicenses,
                    MonthlySavings = unusedLicenses * sub.CostPerLicense
                });
            }

            // 2. Inactive users (no login 30+ days)
            var inactiveUsers = sub.Users.Where(u => 
                u.IsActive && u.LastActiveDate < DateTime.UtcNow.AddDays(-30)).ToList();
            
            if (inactiveUsers.Any())
            {
                report.InactiveUsers.Add(new()
                {
                    Subscription = sub.ServiceNameAr,
                    InactiveCount = inactiveUsers.Count,
                    MonthlySavings = inactiveUsers.Count * sub.CostPerLicense
                });
            }
        }

        // 3. Upcoming renewals
        report.UpcomingRenewals = subscriptions
            .Where(s => s.NextRenewalDate <= DateTime.UtcNow.AddDays(60))
            .Select(s => new RenewalAlert { 
                Subscription = s.ServiceNameAr,
                RenewalDate = s.NextRenewalDate!.Value,
                AnnualCost = s.AnnualCost 
            }).ToList();

        // 4. Duplicate/overlapping services
        report.PotentialDuplicates = subscriptions
            .GroupBy(s => s.Category)
            .Where(g => g.Count() > 1)
            .Select(g => new DuplicateAlert
            {
                Category = g.Key.ToString(),
                Services = g.Select(s => s.ServiceNameAr).ToList()
            }).ToList();

        return report;
    }
}

SQL Schema

CREATE SCHEMA [SaaS];

CREATE TABLE [SaaS].[Subscriptions] (
    [Id] INT IDENTITY(1,1) PRIMARY KEY,
    [SubscriptionCode] NVARCHAR(50) NOT NULL UNIQUE,
    [ServiceNameAr] NVARCHAR(200) NOT NULL,
    [ServiceNameEn] NVARCHAR(200) NOT NULL,
    [ProviderName] NVARCHAR(200) NOT NULL,
    [Category] NVARCHAR(30) NOT NULL,
    [BillingCycle] NVARCHAR(20) NOT NULL,
    [MonthlyCost] DECIMAL(18,2) NOT NULL,
    [AnnualCost] DECIMAL(18,2) NOT NULL,
    [TotalLicenses] INT NOT NULL,
    [UsedLicenses] INT NOT NULL DEFAULT 0,
    [StartDate] DATE NOT NULL,
    [EndDate] DATE NOT NULL,
    [NextRenewalDate] DATE NULL,
    [AutoRenew] BIT NOT NULL DEFAULT 0,
    [Status] NVARCHAR(20) NOT NULL DEFAULT 'Active',
    [DataResidency] NVARCHAR(20) NOT NULL DEFAULT 'SaudiArabia',
    [OwnerDepartmentId] INT NOT NULL,
    [CreatedAt] DATETIME2 NOT NULL DEFAULT GETUTCDATE()
);

-- Cost Overview View
CREATE VIEW [SaaS].[vw_CostOverview] AS
SELECT 
    Category,
    COUNT(*) AS SubscriptionCount,
    SUM(MonthlyCost) AS TotalMonthlyCost,
    SUM(AnnualCost) AS TotalAnnualCost,
    SUM(TotalLicenses) AS TotalLicenses,
    SUM(UsedLicenses) AS TotalUsedLicenses,
    SUM(TotalLicenses - UsedLicenses) AS TotalUnusedLicenses
FROM [SaaS].[Subscriptions] WHERE Status = 'Active'
GROUP BY Category;
Install via CLI
npx skills add https://github.com/mtatwercom/masarat-erp --skill saas-management
Repository Details
star Stars 1
call_split Forks 0
navigation Branch main
article Path SKILL.md
Occupations
More from Creator