Coverage for modules\crm\services.py: 24%

51 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-05 09:25 +0800

1from datetime import timezone, datetime 

2from django.db import transaction 

3from core.exceptions import NotFoundException, BadRequestException 

4from .models import Company, Contact, Pipeline, DealStage, Deal, Activity 

5from modules.authentication.models import User 

6 

7class CRMService: 

8 @staticmethod 

9 def get_or_create_default_pipeline(tenant_id): 

10 pipeline = Pipeline.objects.filter(tenant_id=tenant_id, is_default=True).first() 

11 if not pipeline: 

12 pipeline = Pipeline.objects.create( 

13 tenant_id=tenant_id, 

14 name="Standard Sales Pipeline", 

15 is_default=True 

16 ) 

17 # Default stages 

18 stages = [ 

19 ("Lead In", 10, "#94A3B8"), 

20 ("Contact Made", 25, "#60A5FA"), 

21 ("Proposal Sent", 50, "#F59E0B"), 

22 ("Negotiation", 75, "#8B5CF6"), 

23 ("Won", 100, "#10B981"), 

24 ] 

25 for order, (name, prob, color) in enumerate(stages): 

26 DealStage.objects.create( 

27 tenant_id=tenant_id, 

28 pipeline=pipeline, 

29 name=name, 

30 order=order, 

31 probability=prob, 

32 color=color 

33 ) 

34 return pipeline 

35 

36 @staticmethod 

37 def create_deal(tenant_id, data): 

38 stage = DealStage.objects.filter(id=data.stage_id, tenant_id=tenant_id).first() 

39 if not stage: 

40 raise NotFoundException("Deal stage not found.") 

41 

42 contact = Contact.objects.filter(id=data.contact_id, tenant_id=tenant_id).first() if data.contact_id else None 

43 company = Company.objects.filter(id=data.company_id, tenant_id=tenant_id).first() if data.company_id else None 

44 assigned_to = User.objects.filter(id=data.assigned_to_id).first() if data.assigned_to_id else None 

45 

46 return Deal.objects.create( 

47 tenant_id=tenant_id, 

48 title=data.title, 

49 value=data.value, 

50 currency=data.currency or 'PHP', 

51 pipeline_id=data.pipeline_id, 

52 stage=stage, 

53 contact=contact, 

54 company=company, 

55 expected_close_date=data.expected_close_date, 

56 assigned_to=assigned_to 

57 ) 

58 

59 @staticmethod 

60 def update_deal(tenant_id, deal_id, data): 

61 deal = Deal.objects.filter(id=deal_id, tenant_id=tenant_id).first() 

62 if not deal: 

63 raise NotFoundException("Deal not found.") 

64 

65 if data.title is not None: 

66 deal.title = data.title 

67 if data.value is not None: 

68 deal.value = data.value 

69 if data.stage_id is not None: 

70 stage = DealStage.objects.filter(id=data.stage_id, tenant_id=tenant_id).first() 

71 if stage: 

72 deal.stage = stage 

73 if data.status is not None: 

74 deal.status = data.status 

75 if data.status in ['WON', 'LOST']: 

76 deal.closed_at = datetime.now(timezone.utc) 

77 if data.contact_id is not None: 

78 deal.contact = Contact.objects.filter(id=data.contact_id, tenant_id=tenant_id).first() 

79 if data.company_id is not None: 

80 deal.company = Company.objects.filter(id=data.company_id, tenant_id=tenant_id).first() 

81 if data.expected_close_date is not None: 

82 deal.expected_close_date = data.expected_close_date 

83 if data.assigned_to_id is not None: 

84 deal.assigned_to = User.objects.filter(id=data.assigned_to_id).first() 

85 

86 deal.save() 

87 return deal