Skip to content

Commit d217c98

Browse files
authored
added Service Provider content type
1 parent 48b7fa6 commit d217c98

1 file changed

Lines changed: 356 additions & 0 deletions

File tree

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
# -*- coding: utf-8 -*-
2+
from zope.interface import implementer, alsoProvides
3+
from plone.dexterity.content import Item
4+
from plone.supermodel.model import Schema
5+
from plone.supermodel.directives import fieldset
6+
from plone.autoform.directives import read_permission
7+
from plone.namedfile.field import NamedBlobImage
8+
from plone.rfc822.interfaces import IPrimaryField
9+
from plone.app.textfield import RichText
10+
from plone.app.content.interfaces import INameFromTitle
11+
from ploneorg import _
12+
from ploneorg.vocabularies import countries_vocabulary, languages_vocabulary
13+
14+
from zope import schema
15+
16+
from ploneorg.content.foundationsponsor import isEmail, isHTTP
17+
18+
19+
class IServiceProvider(Schema):
20+
21+
fieldset(
22+
"ContactPerson",
23+
label="Contact Person",
24+
fields=["contact_fullname", "contact_email", "contact_phone", "contact_role"],
25+
)
26+
27+
fieldset(
28+
"Contacts",
29+
label="Contacts",
30+
fields=[
31+
"address",
32+
"city",
33+
"zip_code",
34+
"contact_country",
35+
"email1",
36+
"email2",
37+
"phone1",
38+
"phone2",
39+
"website",
40+
"contact_form_url",
41+
],
42+
)
43+
44+
fieldset(
45+
"Social",
46+
label="Social Media",
47+
fields=["linkedin", "instagram", "youtube", "facebook", "twitter"],
48+
)
49+
50+
fieldset(
51+
"Photos",
52+
label="Photos",
53+
fields=["photo1", "photo2", "photo3", "photo4", "photo5"],
54+
)
55+
56+
title = schema.TextLine(
57+
title=_("Company Name"),
58+
description=_("The official company name."),
59+
required=True,
60+
)
61+
62+
description = schema.Text(
63+
title=_("Short Description"),
64+
description=_("A short summary of the company (1–2 sentences)."),
65+
required=True,
66+
)
67+
68+
logo = NamedBlobImage(
69+
title=_("Logo"),
70+
description=_("Upload the company logo (used as primary image)."),
71+
required=True,
72+
)
73+
74+
sponsor_level = schema.Choice(
75+
title=_("Sponsor Level"),
76+
description=_("Choose the sponsorship level if applicable."),
77+
values=["Basic", "Standard", "Premium"],
78+
required=False,
79+
)
80+
81+
website = schema.URI(
82+
title=_("Website"),
83+
description=_("Main website URL. Must start with http:// or https://."),
84+
required=True,
85+
constraint=isHTTP,
86+
)
87+
88+
rating = schema.Int(
89+
title=_("Rating"),
90+
description=_("Internal rating, between 1 and 5."),
91+
min=1,
92+
max=5,
93+
required=False,
94+
)
95+
96+
languages = schema.List(
97+
title=_("Languages"),
98+
description=_("Languages spoken or supported by the provider."),
99+
value_type=schema.Choice(vocabulary=languages_vocabulary),
100+
required=False,
101+
)
102+
103+
country = schema.Choice(
104+
title=_("Country"),
105+
description=_("Select the primary country of operation."),
106+
vocabulary=countries_vocabulary,
107+
required=False,
108+
)
109+
110+
services = RichText(
111+
title=_("Services"),
112+
description=_("Detailed description of services offered."),
113+
required=False,
114+
)
115+
116+
portfolio = RichText(
117+
title=_("Portfolio / Case Studies"),
118+
description=_("Showcase past projects, implementations, and case studies."),
119+
required=False,
120+
)
121+
122+
certifications = RichText(
123+
title=_("Certifications"),
124+
description=_("Relevant certifications or awards."),
125+
required=False,
126+
)
127+
128+
body = RichText(
129+
title=_("Full Body Text"),
130+
description=_("Full-length company profile, story, or extended content."),
131+
required=False,
132+
)
133+
134+
customer_retention = schema.Int(
135+
title=_("Customer Retention %"),
136+
description=_("Percentage of customers retained (optional metric)."),
137+
required=False,
138+
)
139+
140+
industries = schema.List(
141+
title=_("Industries"),
142+
description=_("Industries served by this provider."),
143+
value_type=schema.Choice(
144+
values=[
145+
"University & Education",
146+
"Non-Profit & NGO",
147+
"Oil & Gas",
148+
"Government & Public Sector",
149+
"Finance & Banking",
150+
"Healthcare & Life Sciences",
151+
"Media & Publishing",
152+
"Transport & Logistics",
153+
"Retail & E-commerce",
154+
"Technology & IT Services",
155+
"Legal Services",
156+
"Professional Services",
157+
"Manufacturing & Industry",
158+
"Energy & Utilities",
159+
"Telecommunications",
160+
]
161+
),
162+
required=False,
163+
)
164+
165+
contact_fullname = schema.TextLine(
166+
title=_("Full Name"),
167+
description=_("Primary contact person full name."),
168+
required=False,
169+
)
170+
171+
contact_email = schema.TextLine(
172+
title=_("Email"),
173+
description=_("Primary contact email address."),
174+
constraint=isEmail,
175+
required=False,
176+
)
177+
178+
contact_phone = schema.TextLine(
179+
title=_("Phone"),
180+
description=_("Primary contact phone number."),
181+
required=False,
182+
)
183+
184+
contact_role = schema.TextLine(
185+
title=_("Role"),
186+
description=_("Job title or role of the contact person."),
187+
required=False,
188+
)
189+
190+
address = schema.TextLine(
191+
title=_("Address"),
192+
description=_("Street address of the office."),
193+
required=False,
194+
)
195+
196+
city = schema.TextLine(
197+
title=_("City"),
198+
description=_("City where the office is located."),
199+
required=False,
200+
)
201+
202+
zip_code = schema.TextLine(
203+
title=_("ZIP Code"),
204+
description=_("Postal/ZIP code."),
205+
required=False,
206+
)
207+
208+
contact_country = schema.Choice(
209+
title=_("Country"),
210+
description=_("Country of the contact office."),
211+
vocabulary=countries_vocabulary,
212+
required=False,
213+
)
214+
215+
email1 = schema.TextLine(
216+
title=_("Email 1"),
217+
description=_("General contact email address."),
218+
constraint=isEmail,
219+
required=False,
220+
)
221+
222+
email2 = schema.TextLine(
223+
title=_("Email 2"),
224+
description=_("Secondary contact email address."),
225+
constraint=isEmail,
226+
required=False,
227+
)
228+
229+
phone1 = schema.TextLine(
230+
title=_("Phone 1"),
231+
description=_("General contact phone number."),
232+
required=False,
233+
)
234+
235+
phone2 = schema.TextLine(
236+
title=_("Phone 2"),
237+
description=_("Secondary contact phone number."),
238+
required=False,
239+
)
240+
241+
contact_form_url = schema.URI(
242+
title=_("Contact Form URL"),
243+
description=_("Direct link to an external contact form."),
244+
constraint=isHTTP,
245+
required=False,
246+
)
247+
248+
linkedin = schema.URI(
249+
title=_("LinkedIn"),
250+
description=_("Link to LinkedIn company or profile page."),
251+
required=False,
252+
constraint=isHTTP,
253+
)
254+
255+
instagram = schema.URI(
256+
title=_("Instagram"),
257+
description=_("Link to Instagram profile."),
258+
required=False,
259+
constraint=isHTTP,
260+
)
261+
262+
youtube = schema.URI(
263+
title=_("YouTube Channel"),
264+
description=_("Link to YouTube company channel."),
265+
required=False,
266+
constraint=isHTTP,
267+
)
268+
269+
facebook = schema.URI(
270+
title=_("Facebook"),
271+
description=_("Link to Facebook page."),
272+
required=False,
273+
constraint=isHTTP,
274+
)
275+
276+
twitter = schema.TextLine(
277+
title=_("Twitter"),
278+
description=_("Twitter handle, without the leading @."),
279+
required=False,
280+
)
281+
282+
photo1 = NamedBlobImage(
283+
title=_("Photo 1"), description=_("Optional showcase photo."), required=False
284+
)
285+
photo2 = NamedBlobImage(
286+
title=_("Photo 2"), description=_("Optional showcase photo."), required=False
287+
)
288+
photo3 = NamedBlobImage(
289+
title=_("Photo 3"), description=_("Optional showcase photo."), required=False
290+
)
291+
photo4 = NamedBlobImage(
292+
title=_("Photo 4"), description=_("Optional showcase photo."), required=False
293+
)
294+
photo5 = NamedBlobImage(
295+
title=_("Photo 5"), description=_("Optional showcase photo."), required=False
296+
)
297+
298+
299+
alsoProvides(IServiceProvider["logo"], IPrimaryField)
300+
301+
302+
@implementer(IServiceProvider)
303+
class ServiceProvider(Item):
304+
305+
def get_full_name(self):
306+
return self.title
307+
308+
@property
309+
def preview_image(self):
310+
return self.logo
311+
312+
@preview_image.setter
313+
def preview_image(self, value):
314+
self.logo = value
315+
316+
@property
317+
def preview_caption(self):
318+
return self.title
319+
320+
@preview_caption.setter
321+
def preview_caption(self, value):
322+
pass
323+
324+
@property
325+
def remoteUrl(self):
326+
return self.website
327+
328+
@remoteUrl.setter
329+
def remoteUrl(self, value):
330+
self.website = value
331+
332+
def toXML(self, schematas=None):
333+
if schematas is None:
334+
schematas = ["Contacts", "ContactPerson", "Social"]
335+
out = f'<serviceprovider id="{self.getId()}">'
336+
for name in schematas:
337+
value = getattr(self, name, None)
338+
if value:
339+
out += f"<{name}>{value}</{name}>"
340+
out += "</serviceprovider>"
341+
return out
342+
343+
344+
class INameFromCompany(INameFromTitle):
345+
def title():
346+
"""Return processed title"""
347+
348+
349+
@implementer(INameFromCompany)
350+
class NameFromCompany(object):
351+
def __init__(self, context):
352+
self.context = context
353+
354+
@property
355+
def title(self):
356+
return self.context.title

0 commit comments

Comments
 (0)