From de6c2757858bab8900bfd9630fc764d9bb8ecf51 Mon Sep 17 00:00:00 2001 From: Deena Date: Sat, 2 Aug 2025 18:44:23 +0530 Subject: [PATCH] Reference for #4 --- .../sos_inside_sales_leads.cpython-310.pyc | Bin 7062 -> 6985 bytes .../models/sos_inside_sales_leads.py | 3 - .../views/sos_inside_sales_leads_view.xml | 2 - sos_inventory/security/security.xml | 7 + sos_marketing/__init__.py | 4 + sos_marketing/__manifest__.py | 33 ++++ sos_marketing/controllers/__init__.py | 3 + sos_marketing/controllers/controllers.py | 22 +++ sos_marketing/demo/demo.xml | 30 +++ sos_marketing/models/__init__.py | 3 + sos_marketing/models/sos_marketing_leads.py | 155 +++++++++++++++ sos_marketing/security/ir.model.access.csv | 4 + sos_marketing/views/menu.xml | 4 + .../views/sos_marketing_leads_view.xml | 180 ++++++++++++++++++ 14 files changed, 445 insertions(+), 5 deletions(-) create mode 100755 sos_marketing/__init__.py create mode 100755 sos_marketing/__manifest__.py create mode 100755 sos_marketing/controllers/__init__.py create mode 100755 sos_marketing/controllers/controllers.py create mode 100755 sos_marketing/demo/demo.xml create mode 100755 sos_marketing/models/__init__.py create mode 100755 sos_marketing/models/sos_marketing_leads.py create mode 100755 sos_marketing/security/ir.model.access.csv create mode 100755 sos_marketing/views/menu.xml create mode 100755 sos_marketing/views/sos_marketing_leads_view.xml diff --git a/sos_inside_sales/models/__pycache__/sos_inside_sales_leads.cpython-310.pyc b/sos_inside_sales/models/__pycache__/sos_inside_sales_leads.cpython-310.pyc index 434cacdbf7c088ac2812cddfbaa300272287d25b..b37697ba8d87736ac4e6ef315ccfc81f65fa78eb 100644 GIT binary patch delta 1726 zcmZuxOKe+J5PjFb_nbKX>Z9%RDw!$E6!;Q6KR0rFk0d`;+XQ~Zj6^3NV_W!bX%4QuH zg<%)$#`b&Q8M(nusn`qqV85(SV|5wb`NW2jWzcc}4z6n#S*izyQ#u@iXV;Zf?}p-1 zQhig3KC=0XBkB-!?ito97Tvw4y6_BjN7+4EC|L&Yu0+l;;|xzo|L^MK=D-9m&2huB zcu!^BJGqoDndt&Qi0rwlsdT}xT9Yda z20tJ|+9Vqm8SNOG6nC|I?5LRb>g{%ef4BiD}K2Kqjy%ru=3pjQn| zQRTzBRX^qi@*QZMXkBRCXbH3)G#%nMw4016i+_O__HAXOqUdY%OyREhl(>S#i1^C) zFgQcRYXm8RX>qyc7W0Wg|FBr|Kd3DS@fha~$eFVXyp+uq3~@M6WM{?wKvGX)Mp?6L zp0#sDqf(%Tsyt7SBY1&eS_}l^9@*)H7!UT3XNUy?gJ3s7mf$pjpCFG=R`IDU=Q0K_ zP!ysYoy~zYn<<%gI%8YhBxy;+Bas%HB*9{7*_eggGMcqeNU!KY9wg0-V4*qoy2ypn zo;Q%Nu8AK)Cu{x8!CXv3b1@Io{`C08{@RnQUx?b-SLFa<%04ek5L_U5y#2EGMA}^0 zQACiFl(liwsDy8kkY*}-r;LJ;p(n*Rh%AUyUEeEm(p8Etkw`sUDiw^h$uCo+J({#~ zrbkIuIgm_g$+YQ2r{O@1<|Yy3ru?hwe*Pp-6?IC-U%fO+z4$B3OEkex&1$@Y}} zjkq2Dv?%MxX+f5tPO{E9N87<8y86G47isA!9d*}}W@RV-Nj$Y9Wq&UoHV(PoLr>g~ zHLN+Q;0FY<_50*io(*{m1d9Z>2;@F3^vbTJan|PasN`AmkI9qAA$Rx*g>q5}lN8FC z>DazRvuIjPafvIDn48GVJE5rfHnPC>ilHd@K0|6uui=mO>8b2fJc#yr?&BJ_#qZHL s`%(B}d3=v&V*4JCR4t{IK~NNNe}Vd+#UHU5c1KJ!jkpJETf*Ld0WRC0Hvj+t delta 1828 zcmah}YiyHc6z<#h>-Tl*b%n0C-Po<)E^JK4V7eh=atW{r-N01GQg*(McHP(QZKrJ6 zTp~+ABS!ZUuLOjIkSK-_{+O7ECip{t_}ADUVvL&b)A+||G@kQThd+omInR5Z^Pbyx z&YOO*{f$0P-tDfi;4kv=E2sSNTOO6MyCTRgtZs%7*w3?M&~Ri`2ur;hbw5NPip-h} zAqztcYNoAF3w7W+Z%and=7f4^kRDO;n6|){s|*^UNqWSjM>DiYj~bby72=pfmzG+z zsL-~GgeB{c_(6eo=m2fa0-ac*UM5grD|Btx8ql@{x?vmiU}KHQ0`LfIhDR}rE!l)z zgh_s$~=saz(V zF@U#~EtTWu{D!R^Z6!ydm?|z5cwBs`H2S;BZt7?{oy(X8?-qY5KeA!*gQMTG4exjl zK`(-s)WVJ@iR};v)tUGJs@S0WfLS!SnJQ-TW-7-A(YjQTNac(|{n+B1!3V^*>Jhd} zbZh%rLM&=G*?yrrb+%6=oZZR@x*rqgock(#sO>>19J>9D^Cnwewq#>qg%F-K*=X7} z%^-|=ElOp!F6+Uw9;E?gOV$ICi|#9I#k1^rjqxV5HR4%K=dfiWy5dEx5~5+tdx2#S z#(J|&D9tD>D6J@Qlo*N*v5VRj#%z}P--W}~RXdD5>8xaf)Z%@WbnAU99(+uKNVvAL zA@QQ?Q{M?PJWKEl!Gt*KzQ)|*SNEXbhohByp8RLey`DP?pGH67@XoSDQS^@K<48+d zp~%z4%&bw);-*x431$cm5lo1my)lO@HzESQjy@o(L69csBcR;;6hW52Ly$u#srZ_n z%S_?Q#JsOstouS%z96pqYS;*9j{_$E8^Fe|e&4aLqJO#8** z6@U1Tvo0}SHF-+*6{Pep5XiPxN!#eEGb)HKTUC3Gy=$BffOzCbY> zU6-5*BWFy}qvGf2#uTnV`!V?~E5y%Iq&k$(=ZuueUnZu}1D?!4p**_%?ci@r|7%l>EMT}GJlLN zWD2Sz^DJ2#2KMUezbdZL)k7-k_6NmEHvFe}Xhn+t3Z+2xeawfeu3#=E)~XxywI)sbPF%JvH+hw)Tr5qVzfT~CBm4b;sQhjTatv|;G{lcY zPpDZTZR&M@SS*C*Sikrw1g*4$5#7!Ir!g@fZg-UH3wN~I!Ea&Q*Wyk%%Q{6{q`&FE f<1e8%pQA`|Iij%d#I?u-yCH1R-AYeYUC{X#@$|8F diff --git a/sos_inside_sales/models/sos_inside_sales_leads.py b/sos_inside_sales/models/sos_inside_sales_leads.py index f73eb95..e750849 100755 --- a/sos_inside_sales/models/sos_inside_sales_leads.py +++ b/sos_inside_sales/models/sos_inside_sales_leads.py @@ -22,8 +22,6 @@ class sos_inside_sales_leads(models.Model): website_url = fields.Char(string="Website URL") vertical_domain = fields.Many2many('sos_vertical_domain',string="Domain / Industry", ondelete="cascade") line_ids_contacts = fields.One2many('sos_leads_contact_lines', 'ref_id', string="Contact Details",copy=True) - remarks=fields.Text(string="Remarks") - linkedin_profile = fields.Char(string="Linkedin profile") # products = fields.Selection( # [ # ('BHMS 1.2V', 'BHMS 1.2V'), @@ -148,7 +146,6 @@ class sos_inside_sales_leads(models.Model): 'location':self.location, 'website_url':self.website_url, 'vertical_domain': [(6, 0, self.vertical_domain.ids)], - 'linkedin_profile':self.linkedin_profile, 'products_interested':[(6, 0,self.products_interested.ids)], 'source':'inside_sales', 'expo_name':self.expo_name, diff --git a/sos_inside_sales/views/sos_inside_sales_leads_view.xml b/sos_inside_sales/views/sos_inside_sales_leads_view.xml index 04c6dc6..0e8622e 100755 --- a/sos_inside_sales/views/sos_inside_sales_leads_view.xml +++ b/sos_inside_sales/views/sos_inside_sales_leads_view.xml @@ -66,7 +66,6 @@ - -

diff --git a/sos_inventory/security/security.xml b/sos_inventory/security/security.xml index a0b8b63..067310f 100755 --- a/sos_inventory/security/security.xml +++ b/sos_inventory/security/security.xml @@ -115,5 +115,12 @@ + + + Marketing User + + + diff --git a/sos_marketing/__init__.py b/sos_marketing/__init__.py new file mode 100755 index 0000000..aa4d0fd --- /dev/null +++ b/sos_marketing/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import controllers +from . import models diff --git a/sos_marketing/__manifest__.py b/sos_marketing/__manifest__.py new file mode 100755 index 0000000..f11cfee --- /dev/null +++ b/sos_marketing/__manifest__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +{ + 'name': "SOS Marketing", + + 'summary': "Marketing", + + 'description': """ +Long description of module's purpose + """, + + 'author': "Deena", + 'website': "https://sosaley.com", + + 'category': 'Inventory', + 'version': '17.0.1.0.0', + # any module necessary for this one to work correctly + 'depends': ['base','web','mail','sos_inventory','sos_sales'], + + # always loaded + 'data': [ + 'security/ir.model.access.csv', + 'views/menu.xml', + 'views/sos_marketing_leads_view.xml' + ], + # only loaded in demonstration mode + 'demo': [ + 'demo/demo.xml', + ], + 'installable': True, + 'application': True, + 'license': 'LGPL-3' +} + diff --git a/sos_marketing/controllers/__init__.py b/sos_marketing/controllers/__init__.py new file mode 100755 index 0000000..b0f26a9 --- /dev/null +++ b/sos_marketing/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers diff --git a/sos_marketing/controllers/controllers.py b/sos_marketing/controllers/controllers.py new file mode 100755 index 0000000..2d78fa6 --- /dev/null +++ b/sos_marketing/controllers/controllers.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# from odoo import http + + +# class SosMarketing(http.Controller): +# @http.route('/sos_marketing/sos_marketing', auth='public') +# def index(self, **kw): +# return "Hello, world" + +# @http.route('/sos_marketing/sos_marketing/objects', auth='public') +# def list(self, **kw): +# return http.request.render('sos_marketing.listing', { +# 'root': '/sos_marketing/sos_marketing', +# 'objects': http.request.env['sos_marketing.sos_marketing'].search([]), +# }) + +# @http.route('/sos_marketing/sos_marketing/objects/', auth='public') +# def object(self, obj, **kw): +# return http.request.render('sos_marketing.object', { +# 'object': obj +# }) + diff --git a/sos_marketing/demo/demo.xml b/sos_marketing/demo/demo.xml new file mode 100755 index 0000000..f4dc83d --- /dev/null +++ b/sos_marketing/demo/demo.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/sos_marketing/models/__init__.py b/sos_marketing/models/__init__.py new file mode 100755 index 0000000..87c4fbc --- /dev/null +++ b/sos_marketing/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import sos_marketing_leads diff --git a/sos_marketing/models/sos_marketing_leads.py b/sos_marketing/models/sos_marketing_leads.py new file mode 100755 index 0000000..f09f16d --- /dev/null +++ b/sos_marketing/models/sos_marketing_leads.py @@ -0,0 +1,155 @@ + +from odoo import models, fields, api + + +class sos_marketing(models.Model): + _name = 'sos_marketing_leads' + _description = 'Marketing Leads' + _rec_name = 'company_name' + + company_name = fields.Char(string="Company Name") + website_url = fields.Char(string="Website URL") + country = fields.Many2one( + 'res.country', + string='Country', + default=lambda self: self.env['res.country'].search([('code', '=', 'IN')], limit=1) +) + location = fields.Char(string="City/State") + expo_option=fields.Boolean(string="Expo",default="True") + conference_option=fields.Boolean(string="Conference") + linkedin_groups_option=fields.Boolean(string="LinkedIn Groups") + linkedin_poll_option=fields.Boolean(string="LinkedIn Poll") + direct_company=fields.Boolean(string="Direct Company") + expo_participated_option=fields.Boolean(string="Expo [Paricipated]") + #Expo + expo_name = fields.Char(string="Expo Name") + expo_date_from = fields.Date(string="Expo Date From") + expo_date_to = fields.Date(string="Expo Date To") + expo_Location = fields.Char(string="Expo Location") + #Conference + conference_name = fields.Char(string="Conference Name") + conference_date_from = fields.Date(string="Conference Date From") + conference_date_to = fields.Date(string="Conference Date To") + conference_Location = fields.Char(string="Conference Location") + #Linkedin Group + linkedin_group_name = fields.Char(string="LinkedIn Group Name") + #Linkedin poll + linkedin_post_url = fields.Char(string="LinkedIn Post URL") + vertical_domain = fields.Many2many('sos_vertical_domain',string="Vertical/Domain", ondelete="cascade") + line_ids_contacts = fields.One2many('sos_marketing_leads_contact_lines', 'ref_id', string="Contact Details",copy=True) + move_to_inside_sales = fields.Many2many('res.users',string="Move Lead to", domain=lambda self: [('groups_id', 'in', self.env.ref('sos_inventory.sos_inside_sales_user').ids + self.env.ref('sos_inventory.sos_sales_user').ids)]) + cc_mail = fields.Many2one('res.users',string="CC to", domain=lambda self: [('groups_id', 'in', self.env.ref('sos_inventory.sos_sales_user').ids + self.env.ref('sos_inventory.sos_inside_sales_user').ids)]) + move_div_display = fields.Boolean(default=False,string="Moved to Sales") + moved_on = fields.Date(string="Moved On") + @api.onchange('expo_option') + def _onchange_expo(self): + if self.expo_option: + self.conference_option = False + self.linkedin_groups_option = False + self.linkedin_poll_option = False + self.direct_company = False + self.expo_participated_option = False + + @api.onchange('conference_option') + def _onchange_conference(self): + if self.conference_option: + self.expo_option = False + self.linkedin_groups_option = False + self.linkedin_poll_option = False + self.direct_company = False + self.expo_participated_option = False + + @api.onchange('linkedin_groups_option') + def _onchange_linkedin_groups(self): + if self.linkedin_groups_option: + self.expo_option = False + self.conference_option = False + self.linkedin_poll_option = False + self.direct_company = False + self.expo_participated_option = False + + @api.onchange('linkedin_poll_option') + def _onchange_linkedin_poll(self): + if self.linkedin_poll_option: + self.expo_option = False + self.conference_option = False + self.linkedin_groups_option = False + self.direct_company = False + self.expo_participated_option = False + + @api.onchange('direct_company') + def _onchange_direct_company(self): + if self.direct_company: + self.expo_option = False + self.conference_option = False + self.linkedin_groups_option = False + self.linkedin_poll_option = False + self.expo_participated_option = False + + @api.onchange('expo_participated_option') + def _onchange_expo_participated(self): + if self.expo_participated_option: + self.expo_option = False + self.conference_option = False + self.linkedin_groups_option = False + self.linkedin_poll_option = False + self.direct_company = False + def action_move_to_inside_sales(self): + if self.move_to_inside_sales: + for user in self.move_to_inside_sales: + body_html = f""" +

Below Lead is moved to Inside-Sales

+ """ + subject = f"New Lead Received - {self.company_name}" + send_email = self.env['sos_common_scripts'] + send_email.send_direct_email(self.env,"sos_marketing_leads",self.id,user.login,subject,body_html,self.cc_mail.login) + new_record = self.env['sos_inside_sales_leads'].create({ + 'company_name': self.company_name, + 'location':self.location, + 'website_url':self.website_url, + 'vertical_domain': [(6, 0, self.vertical_domain.ids)] + }) + if new_record: + if self.line_ids_contacts: + for contact in self.line_ids_contacts: + self.env['sos_leads_contact_lines'].create({ + 'ref_id': new_record.id, + 'name': contact.name, + 'dept': contact.dept, + 'email': contact.email, + 'mobile_number': contact.mobile_number, + 'set_as_primary': contact.set_as_primary, + 'linkedin_profile': contact.linkedin_profile, + 'remarks': contact.remarks + }) + self.move_div_display = True + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'message': "Moved Successfully", + 'type': 'success', + 'sticky': False + } + } +class SOS__Marketing_Leads_Line(models.Model): + _name = 'sos_marketing_leads_contact_lines' + _description = 'Marketing Leads Contact Lines' + + ref_id = fields.Many2one('sos_marketing_leads', string="Marketing Leads", ondelete="cascade") + name = fields.Char(string="Name") + dept = fields.Char(string="Designation") + email = fields.Char(string="Email Id") + mobile_number = fields.Char(string="Contact No") + set_as_primary = fields.Boolean(string="Set Primary") + linkedin_profile = fields.Char(string="LinkedIn Profile") + linkedin_invited_on = fields.Char(string="LinkedIn Conn Invited On") + linkedin_invitation_status = fields.Selection( + [ + ('Yet To Accept', 'Yet To Accept'), + ('Accepted', 'Accepted'), + ('No Match', 'No Match'), + ('No Requirement', 'No Requirement') + ], + string="LinkedIn Conn Invitation Status") + remarks = fields.Text(string="Remarks") \ No newline at end of file diff --git a/sos_marketing/security/ir.model.access.csv b/sos_marketing/security/ir.model.access.csv new file mode 100755 index 0000000..8248802 --- /dev/null +++ b/sos_marketing/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_sos_marketing_leads,sos_marketing_leads access for all,model_sos_marketing_leads,base.group_user,1,1,1,1 +access_sos_marketing_leads_contact_lines,sos_marketing_leads_contact_lines access for all,model_sos_marketing_leads_contact_lines,base.group_user,1,1,1,1 + diff --git a/sos_marketing/views/menu.xml b/sos_marketing/views/menu.xml new file mode 100755 index 0000000..3f31a98 --- /dev/null +++ b/sos_marketing/views/menu.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/sos_marketing/views/sos_marketing_leads_view.xml b/sos_marketing/views/sos_marketing_leads_view.xml new file mode 100755 index 0000000..f0b55b7 --- /dev/null +++ b/sos_marketing/views/sos_marketing_leads_view.xml @@ -0,0 +1,180 @@ + + + + Marketing Leads + ir.actions.act_window + sos_marketing_leads + tree,form,kanban + + + + + + sos_marketing_leads.view.tree + sos_marketing_leads + + + + + + + + + + + + + + Form + sos_marketing_leads + +
+ + +

Marketing Leads




+ + + + + + + + + + +
+





+

Company Info

+ + + + + + + + + + + + + +

+ +
+ +

Expo Details

+ + + + + + + + + + + +
+ +
+

Conference Details

+ + + + + + + + + + + +
+ +
+

LinkedIn Group Details

+ + + + + +
+ +
+

LinkedIn Poll Details

+ + + + + +
+ +
+ +

Expo[Participated] Details

+ + + + + + + + + + + +
+

+ +

Contact Details

+ + + + + + + + + + + + + + +

+
+
+ +
+ + + + +
Move Lead To
Cc To
+
+
+
+
+ +
+ + + +
Moved To
Moved On
+
+
+
+
+
+
+ + + +