This commit is contained in:
zainab8585 2024-08-01 09:40:23 +02:00
parent 86e2908cd2
commit f3f5316996
75 changed files with 1102 additions and 45 deletions

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-29 11:27+0000\n"
"PO-Revision-Date: 2024-07-29 11:27+0000\n"
"POT-Creation-Date: 2024-07-31 12:13+0000\n"
"PO-Revision-Date: 2024-07-31 12:13+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@ -126,9 +126,9 @@ msgstr ""
#. module: dev_membership
#: model_terms:ir.ui.view,arch_db:dev_membership.res_dev_membership_config_settings_view_form
msgid ""
"<span class=\"o_form_label\">Membership Cancellation\".\n"
"<span class=\"o_form_label\">Membership Auto Cancellation\".\n"
" </span>"
msgstr "إلغاء العضوية"
msgstr "إلغاء تلقائي للعضويات المنتهية بعد تجاوز المدة المحدده وعدم التجديد"
#. module: dev_membership
#: model_terms:ir.ui.view,arch_db:dev_membership.res_dev_membership_config_settings_view_form
@ -664,14 +664,10 @@ msgstr ""
#. module: dev_membership
#: model:ir.model.fields,field_description:dev_membership.field_membership_level__max
#: model:ir.model.fields,field_description:dev_membership.field_membership_level__min
msgid "Maximum"
msgstr "الحد الاعلي"
#. module: dev_membership
#: model:ir.model.fields,field_description:dev_membership.field_membership_level__min
msgid "Minimum"
msgstr "الحد الادني"
#. module: dev_membership
#: model:ir.actions.act_window,name:dev_membership.action_members
#: model:ir.model.fields,field_description:dev_membership.field_membership_cancellation_request__member_id
@ -703,6 +699,12 @@ msgstr "العضوية"
msgid "Membership %s is Cancelled"
msgstr "تم إلغاء العضوية %s"
#. module: dev_membership
#: model_terms:ir.ui.view,arch_db:dev_membership.res_dev_membership_config_settings_view_form
msgid "Membership Auto Cancellation\"."
msgstr "إلغاء تلقائي للعضويات المنتهية بعد تجاوز المدة المحدده وعدم التجديد"
#. module: dev_membership
#: model:ir.model.fields,field_description:dev_membership.field_product_product__membership_benefits
#: model:ir.model.fields,field_description:dev_membership.field_product_template__membership_benefits
@ -734,11 +736,6 @@ msgstr ""
msgid "Membership Cancellation Requests"
msgstr "طلبات إلغاء العضوية"
#. module: dev_membership
#: model_terms:ir.ui.view,arch_db:dev_membership.res_dev_membership_config_settings_view_form
msgid "Membership Cancellation\"."
msgstr "إلغاء العضوية"
#. module: dev_membership
#: model:ir.model.fields,field_description:dev_membership.field_membership_level__color
msgid "Membership Card Color"
@ -927,7 +924,7 @@ msgstr ""
#: code:addons/dev_membership/models/dev_membership.py:0
#, python-format
msgid "Membership is only allowed for %s"
msgstr ""
msgstr "العضوية مسموحة فقط لـ"
#. module: dev_membership
#: model:ir.model,name:dev_membership.model_membership_request_cancel_wizard
@ -965,9 +962,9 @@ msgid "Messages"
msgstr ""
#. module: dev_membership
#: model:ir.model.fields,field_description:dev_membership.field_membership_level__years
msgid "NO Of Years Subscription."
msgstr "عدد سنوات الاشتراك"
#: model:ir.model.fields,field_description:dev_membership.field_dev_membership__mmembrship_level
msgid "Mmembrship level"
msgstr ""
#. module: dev_membership
#: model:ir.model.fields.selection,name:dev_membership.selection__product_template__interval__month
@ -982,6 +979,11 @@ msgstr "شهر"
msgid "My Activity Deadline"
msgstr ""
#. module: dev_membership
#: model:ir.model.fields,field_description:dev_membership.field_membership_level__years
msgid "NO Of Years Subscription."
msgstr "عدد سنوات الاشتراك"
#. module: dev_membership
#: model:ir.model.fields,field_description:dev_membership.field_dev_membership__name
#: model:ir.model.fields,field_description:dev_membership.field_membership_level__name
@ -1149,6 +1151,12 @@ msgstr ""
msgid "Request Date"
msgstr "تاريخ الطلب"
#. module: dev_membership
#: code:addons/dev_membership/models/membership_cancel_request.py:0
#, python-format
msgid "Requests can only be deleted if they are in the draft state."
msgstr يمكن حذف الطلبات فقط إذا كانت في حالة المسودة."
#. module: dev_membership
#: model_terms:ir.ui.view,arch_db:dev_membership.view_search_res_partner
msgid "Res Partner Search"
@ -1222,13 +1230,13 @@ msgstr "الضرائب"
#: code:addons/dev_membership/models/dev_membership.py:0
#, python-format
msgid "The member must be at least 18 years old."
msgstr ""
msgstr "يجب أن يكون عمر العضو 18 عامًا على الأقل"
#. module: dev_membership
#: code:addons/dev_membership/models/dev_membership.py:0
#, python-format
msgid "The member's nationality does not meet the membership requirements"
msgstr ""
msgstr "جنسية العضو لا تفي بمتطلبات العضوية"
#. module: dev_membership
#: model:ir.model.fields,help:dev_membership.field_dev_membership__activity_exception_decoration

View File

@ -20,7 +20,7 @@ class DevMembership(models.Model):
_description = 'Dev Membership'
_order = 'name desc'
membrship_level = fields.Many2one('membership.level',string='Membrship level',store=True, required=False,compute='_compute_membership_level')
name = fields.Char(string='Name', readonly=1)
date = fields.Date(string="Request Date", tracking=3, required=1, default=lambda self: datetime.now().date())
from_date = fields.Date(string="Membership From Date", tracking=3, required=1, default=lambda *a: (datetime.now().date()))
@ -49,6 +49,24 @@ class DevMembership(models.Model):
user_id = fields.Many2one('res.users', string='Resposible', default=lambda self:self.env.user)
cancel_reasone = fields.Char(string='Cancel Membership Reason')
# subscription_years = fields.Integer(string='Subscription Years', compute='_compute_subscription_years', store=True)
# @api.depends('partner_id')
# def _compute_subscription_years(self):
# for record in self:
# total_years = 0
# memberships = self.env['dev.membership'].search([
# ('partner_id', '=', record.partner_id.id),
# ('state', '=', 'active')
# ])
# for membership in memberships:
# if membership.from_date and membership.to_date:
# from_date = fields.Date.from_string(membership.from_date)
# to_date = fields.Date.from_string(membership.to_date)
# years_difference = (to_date - from_date).days / 365.25 # حساب الفرق بالسنوات
# total_years += years_difference
#
# record.subscription_years = total_years
@api.onchange('product_id')
def _onchange_membership_type(self):
if self.product_id:
@ -127,11 +145,11 @@ class DevMembership(models.Model):
self.to_date = self.from_date + relativedelta(days=+self.duration)
def action_confirm_membership(self):
if self.product_id.nationality_ids and self.product_id.age:
if self.partner_id.nationality_id not in self.product_id.nationality_ids:
raise ValidationError(_("The member's nationality does not meet the membership requirements"))
if self.partner_id.age <18:
raise ValidationError(_('The member must be at least 18 years old.'))
if self.partner_id.gender != self.product_id.gender:
if self.partner_id.gender != self.product_id.gender and self.product_id.gender!=False:
raise ValidationError(_('Membership is only allowed for %s') % self.product_id.gender)
self.state = 'confirm'
@ -270,7 +288,7 @@ class DevMembership(models.Model):
def datetime_convert(self):
convert_date = self.to_date.strftime("%d-%m-%Y")
return convert_date
def create_membership_invoice(self):
vals= {'move_type': 'out_invoice',
'partner_id': self.partner_id.id,
@ -280,8 +298,49 @@ class DevMembership(models.Model):
}
invoice_id = self.env['account.move'].create(vals)
self.invoice_id = invoice_id and invoice_id.id or False
@api.depends('membership_fees')
def _compute_membership_level(self):
for record in self:
total_fees = 0
memberships = self.env['dev.membership'].search([
('partner_id', '=', record.partner_id.id),
('state', '=', 'active')
])
total_fees = sum(membership.membership_fees for membership in memberships)
# البحث عن مستوى العضوية بناءً على إجمالي الرسوم
level_by_fees = self.env['membership.level'].search([
('min', '<=', total_fees),
('max', '>=', total_fees)
], limit=1)
# البحث عن مستوى العضوية بناءً على عدد السنوات (≥ 3 سنوات)
level_by_years = self.env['membership.level'].search([
('years', '>=', 3)
], limit=1)
total_duration = sum(membership.duration for membership in memberships)
# تعيين مستوى العضوية
# if level_by_years:
#
# record.membrship_level_id = level_by_years.id
if level_by_fees:
record.membrship_level = level_by_fees.id
if total_duration>=level_by_years.years and total_fees<=level_by_years.min:
record.membrship_level = level_by_fees.id
# level = self.env['membership.level'].search(
# ['|',
# '&', ('min', '<=', total_fees), ('max', '>=', total_fees),
# ('years', '<=', total_duration)],
# limit=1
# )
#
# if level:
# record.membrship_level = level.id
# else:
# record.membrship_level = False
def view_invoice(self):
if self.invoice_id:
ctx = dict(create=False)

View File

@ -1,4 +1,5 @@
from odoo import models, fields, api,_
from odoo.exceptions import UserError, ValidationError
class MembershipCancellationRequest(models.Model):
_name = 'membership.cancellation.request'
@ -6,9 +7,9 @@ class MembershipCancellationRequest(models.Model):
_inherit = ['mail.thread', 'mail.activity.mixin']
_rec_name = 'member_id'
member_id = fields.Many2one('res.partner', string='Member', required=True)
membership_type_id = fields.Many2one('product.template', string='Membership Type', required=True)
membership_id = fields.Many2one('dev.membership', string='Membership', required=True)
membership_id = fields.Many2one('dev.membership', string='Membership',required=True)
member_id = fields.Many2one('res.partner', string='Member',related='membership_id.partner_id',store=True, required=True)
membership_type_id = fields.Many2one('product.product',related='membership_id.product_id',store=True, string='Membership Type', required=True)
cancel_reason = fields.Char(string='Cancellation Reason', required=True)
request_date = fields.Datetime(string='Request Date', default=fields.Datetime.now)
state = fields.Selection([
@ -25,3 +26,8 @@ class MembershipCancellationRequest(models.Model):
def action_reject(self):
for rec in self:
rec.state = 'rejected'
def unlink(self):
for record in self:
if record.state != 'draft':
raise UserError(_("Requests can only be deleted if they are in the draft state."))
return super(MembershipCancellationRequest, self).unlink()

View File

@ -18,6 +18,7 @@ class PartnerExtended(models.Model):
is_member = fields.Boolean(string='Is Member')
membership_count = fields.Integer(string="Membership Count", compute="_get_membership_count")
active_membership_id = fields.Many2one('dev.membership', string='Membership', compute='check_active_membership')
membrship_level = fields.Many2one(string='Mmembrship level', required=False,related='active_membership_id.membrship_level')
nationality_id = fields.Many2one('res.country', string="Nationality")
is_membership_expire = fields.Boolean('Expire Membership',store=True, compute='check_active_membership')
@ -49,12 +50,32 @@ class PartnerExtended(models.Model):
partner.memebership_status = ''
if partner.membership_count == 0:
partner.memebership_status = 'No Membership'
else:
if partner.is_membership_expire:
partner.memebership_status = 'Membership Expire'
if partner.active_membership_id:
partner.memebership_status = 'Membership : ' + partner.active_membership_id.name
else:
if partner.active_membership_id:
partner.memebership_status = 'Membership : ' + partner.active_membership_id.name
# البحث عن حالة الاشتراك الأخيرة
last_membership = self.env['dev.membership'].search([('partner_id', '=', partner.id)], order='to_date desc', limit=1)
print('last_membership = ',last_membership)
if last_membership:
if last_membership.state=='draft':
partner.memebership_status = 'Membership Waitting'
elif last_membership.state=='cancel':
partner.memebership_status = 'Membership Cancelled'
elif last_membership.state=='confirm':
if not last_membership.invoice_id and not last_membership.is_free:
partner.memebership_status = 'Membership Waitting invoice'
elif last_membership.invoice_id.payment_state in ['paid','in_payment']:
partner.memebership_status = 'Membership Paid'
elif last_membership.invoice_id.payment_state not in ['paid','in_payment']:
partner.memebership_status = 'Membership Waitting Paid'
##############################################################################################################################################
# if partner.is_membership_expire:
# partner.memebership_status = 'Membership Expire'
# else:
if partner.active_membership_id:
partner.memebership_status = 'Membership : ' + partner.active_membership_id.name
def check_active_membership(self):
for partner in self:
@ -86,4 +107,4 @@ class PartnerExtended(models.Model):
'view_mode': 'tree,form',
'target': 'current',
'context': ctx,
}
}

View File

@ -8,6 +8,7 @@
<tree string="Dev Membership Tree View">
<field name="name"/>
<field name="partner_id"/>
<field name="membrship_level" optional="hide"/>
<field optional="hide" name="id_no"/>
<field optional="hide" name="phone"/>
<field optional="hide" name="email"/>
@ -65,12 +66,21 @@
</div>
</button>
</div>
<!-- &lt;!&ndash; Payment status for invoices / receipts &ndash;&gt;-->
<!-- <widget name="web_ribbon" title="Paid" attrs="{'invisible': ['|', ('payment_state', '!=', 'paid'), ('move_type', 'not in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt'))]}"/>-->
<!-- <widget name="web_ribbon" title="In Payment" attrs="{'invisible': ['|', ('payment_state', '!=', 'in_payment'), ('move_type', 'not in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt'))]}"/>-->
<!-- <widget name="web_ribbon" title="Partial" attrs="{'invisible': ['|', ('payment_state', '!=', 'partial'), ('move_type', 'not in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt'))]}"/>-->
<!-- <widget name="web_ribbon" title="Reversed" bg_color="bg-danger" attrs="{'invisible': [('payment_state', '!=', 'reversed')]}"/>-->
<!-- <widget name="web_ribbon" text="Invoicing App Legacy" bg_color="bg-info" attrs="{'invisible': [('payment_state', '!=', 'invoicing_legacy')]}" tooltip="This entry has been generated through the Invoicing app, before installing Accounting. It has been disabled by the 'Invoicing Switch Threshold Date' setting so that it does not impact your accounting."/>-->
<h2>
<field name="name"/>
</h2>
<group>
<group>
<field name="partner_id" attrs="{'readonly': ([('state', '!=', 'draft')])}"/>
<field name="membrship_level"/>
<field name="id_no"/>
<field invisible='1' name="is_free"/>
<field name="phone"/>
@ -136,6 +146,7 @@
<field name="from_date"/>
<field name="to_date"/>
<field name="state"/>
<field name="membrship_level"/>
<field name="activity_ids" widget="list_activity" optional="show"/>
<templates>
<t t-name="kanban-box">
@ -167,6 +178,8 @@
<h5>
<field name="state" widget="label_selection"
options="{'classes': {'draft': 'warning', 'expire': 'danger', 'confirm': 'success', 'active' : 'success'}}"/>
<field name="membrship_level" widget="label_selection"
options="{'classes': {'draft': 'warning', 'expire': 'danger', 'confirm': 'success', 'active' : 'success'}}"/>
</h5>
</div>
<div class="o_kanban_record_bottom">

View File

@ -13,14 +13,27 @@
</header>
<sheet>
<group>
<field name="member_id"/>
<field name="membership_type_id"/>
<field name="membership_id"/>
<field name="cancel_reason"/>
<field name="request_date"/>
<group>
<field domain='[("state","in",["active","expire"])]' attrs="{'readonly': [('state', '!=', 'draft')]}" name="membership_id"/>
<field attrs="{'readonly': [('state', '!=', 'draft')]}" name="member_id"/>
<field attrs="{'readonly': [('state', '!=', 'draft')]}" name="membership_type_id"/>
</group>
<gruop>
<field attrs="{'readonly': [('state', '!=', 'draft')]}" name="request_date"/>
</gruop>
</group>
</sheet>
<div>
<h3>
<label for="cancel_reason"/>
<field attrs="{'readonly': [('state', '!=', 'draft')]}" name="cancel_reason"/>
</h3></div>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids"/>
<field name="activity_ids" />
<field name="message_ids"/>
</div>
</form>
</field>
</record>
@ -31,9 +44,9 @@
<field name="model">membership.cancellation.request</field>
<field name="arch" type="xml">
<tree string="Membership Cancellation Requests">
<field name="membership_id"/>
<field name="member_id"/>
<field name="membership_type_id"/>
<field name="membership_id"/>
<field name="cancel_reason"/>
<field name="request_date"/>
<field name="state"/>

View File

@ -13,7 +13,9 @@
<field name="identification_number" optional="show"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
<field name="join_date" optional="show"/>
<field name="membrship_level" optional="hide"/>
<field name="memebership_end_date" optional="show"/>
<field name="product_id" optional="show"/>
<field name="category_id" widget="many2many_tags" optional="show"/>
<field name="activity_ids" widget="list_activity" optional="show"/>
@ -46,6 +48,7 @@
<field name="mobile"/>
<field name="state_id"/>
<field name="join_date"/>
<field name="membrship_level"/>
<field name="category_id" widget="many2many_tags"/>
<field name="image_128"/>
@ -117,6 +120,8 @@
<span>
<b style="color:#7C7BAD">
<field name="memebership_status"/>
</b><br/><b style="color:#7C7BAD">
<field name="membrship_level"/>
</b>
</span>
<div class="o_row">
@ -156,7 +161,7 @@
<field name="gender"/>
<field name="nationality_id"/>
<field name="birth_date"/>
<field name="age"/>
<field name="age"/><field name="membrship_level"/>
</xpath>
<xpath expr="//field[@name='function']" position="after">
<field name="employer"/>

View File

@ -84,10 +84,10 @@
<div class="col-12 col-lg-6 o_setting_box" id="late_cancellfine">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">Membership Cancellation".
<span class="o_form_label">Membership Auto Cancellation".
</span>
<div class="text-muted">
Membership Cancellation".
Membership Auto Cancellation".
</div>
<div class="text-muted content-group mt16">
<field name="post_expiry_period"/>

View File

@ -8,6 +8,8 @@ class MembershipRefues(models.TransientModel):
_name = "membership.request.cancel.wizard"
_description = "Membership refuse Reason wizard"
reason_id = fields.Many2one('cancellation.reason',string='Cancel Membership Reason' ,required=True)
request_id = fields.Many2one('dev.membership')
user_id = fields.Many2one('res.users', string='User', default=lambda self: self.env.user,)
@ -50,5 +52,13 @@ class MembershipRefues(models.TransientModel):
'cancel_reason': self.reason_id.name,
'state': 'draft'
})
return {'type': 'ir.actions.act_window_close'}
# return {'type': 'ir.actions.act_window_close'}
return {
'type': 'ir.actions.act_window',
'name': 'Membership Cancellation Requests',
'view_mode': 'tree,form',
'res_model': 'membership.cancellation.request',
'context': dict(self.env.context, create=False)
}

View File

@ -14,6 +14,7 @@
<button string='Cancel Membership' name="request_cancel_reason" type="object" class="oe_highlight"/>
<button string="Ignore" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>

View File

@ -0,0 +1,45 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/AGPL-3.0-standalone.html
:alt: License: AGPL-3
Membership Card
===============
Print membership card either with membership product or free member.
Configuration
=============
* No additional configurations needed
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
License
-------
Affero General Public License, Version 3 (AGPL v3).
(https://www.odoo.com/documentation/user/16.0/legal/licenses/licenses.html)
Credits
-------
Developer : (V15) Saneen K, Contact : odoo@cybrosys.com
Contacts
--------
* Mail Contact : odoo@cybrosys.com
* Website : https://cybrosys.com
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
Maintainer
==========
.. image:: https://cybrosys.com/images/logo.png
:target: https://cybrosys.com
This module is maintained by Cybrosys Technologies.
For support and more information, please visit `Our Website <https://cybrosys.com/>`__
Further information
===================
HTML Description: `<static/description/index.html>`__

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Saneen K (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from . import models

View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Saneen K (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
{
'name': 'Membership Card',
'version': "15.0.1.0.0",
'category': 'Extra Tools',
'summary': "Print membership card either with membership product or"
" free member",
'description': 'This module helps to Print Membership Card wisely if'
' customer is having membership product it will print card '
'according to membership product if not it will print card '
'as free member.',
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['membership','dev_membership'],
'data': [
'report/membership_card_reports.xml',
'data/ir_actions_server_data.xml',
],
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
'auto_install': False,
'application': False,
}

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Used to bring a menu inside action menu -->
<record id="server_action_get_card" model="ir.actions.server">
<field name="name">Print Membership Card</field>
<field name="model_id" ref="base.model_res_partner"/>
<field name="binding_model_id" ref="base.model_res_partner"/>
<field name="state">code</field>
<field name="code">action = records.server_action_get_card()</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,11 @@
## Module <membership_card_odoo>
#### 21.12.2023
#### Version 15.0.1.0.0
#### ADD
- Initial Commit for Membership Card
#### 02.02.2024
#### Version 15.0.1.0.1
#### UPDATE
- Fixed the issue of not printing the arabic words in the report

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Saneen K (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from . import res_partner

View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Saneen K (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
from odoo.exceptions import ValidationError
class ResPartner(models.Model):
""" Inherit the res. partner to make existing field required. """
_inherit = 'res.partner'
image_1920 = fields.Image(max_width=1920, max_height=1920,
required=True, string="Image",
help="The field hold the image of customer")
phone = fields.Char(unaccent=False, required=True,
string="Phone",
help="The field hold the phone number of customer")
function = fields.Char(string='Job Position',
help="The field hold the job position of customer")
def server_action_get_card(self):
""" Used to fetch data from res. partner to pass in template"""
partner_id = self.env['res.partner'] \
.browse(self.env.context.get('active_ids'))
company_id = self.env.company
if self.is_member or partner_id.member_lines:
data = {
'name': partner_id.name,
'image': partner_id.image_1920,
'phone': partner_id.phone,
'function': partner_id.function,
'free_member': partner_id.is_member,
'membership_product': partner_id.member_lines.
mapped('membership_id.name'),
'start_date': partner_id.join_date,
'end_date': partner_id.memebership_end_date,
'company_name': company_id.name,
'company_address': company_id.street,
'city': company_id.city,
'country': company_id.country_id.name,
'state': company_id.state_id.name,
'company_email': company_id.email,
'company_phone': company_id.phone,
'website': company_id.website,
}
return self.env.ref('membership_card_odoo.action_membership'
'_card').report_action(None, data=data)
raise ValidationError(
'Need to buy membership inorder to print membership card')

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Used to change the format of pdf. -->
<record id="paperformat_card" model="report.paperformat">
<field name="name">Custom Paper</field>
<field name="default" eval="True"/>
<field name="format">custom</field>
<field name="page_height">95</field>
<field name="page_width">60</field>
<field name="orientation">Landscape</field>
<field name="margin_top">5.00</field>
<field name="margin_bottom">5.00</field>
<field name="margin_left">5.0</field>
<field name="margin_right">5.0</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">35</field>
<field name="dpi">125</field>
</record>
<!--Report Action-->
<record id="action_membership_card" model="ir.actions.report">
<field name="name">Membership Card</field>
<field name="model">res.partner</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">membership_card_odoo.print_member_ship_card</field>
<field name="report_file">membership_card_odoo.print_member_ship_card</field>
<field name="paperformat_id"
ref="membership_card_odoo.paperformat_card"/>
</record>
<!-- Template to print Pdf. -->
<template id="print_member_ship_card">
<t t-call="web.html_container">
<t t-call="web.internal_layout">
<div style="border: 2px solid black; padding: 15px; margin-bottom: 40px; height: 90%;">
<tr t-if="free_member==True">
<div style="border-bottom: 2px solid black; margin-bottom: 15px; font-size: 15px !important;">
<h2 style=" text-align: center;">Free Member</h2>
</div>
</tr>
<tr t-else="free_member==False">
<tr>
<div style="border-bottom: 2px solid black; margin-bottom: 15px;">
<h2 style="text-align:center;">
<t t-esc="membership_product[0]"/>
</h2>
</div>
</tr>
</tr>
<div style="display: -webkit-box; display: flex; -webkit-box-pack: space-between; justify-content: space-between; -webkit-align-self: center align-self: center; align-items: center; ">
<div>
<img style="width: 120px; border-radius: 5px;"
t-attf-src="data:image/*;base64,{{image}}"/>
</div>
<div class="session_1"
style="margin-left: 15px; margin-top: 0px; padding-top: 0px; ">
<tr t-if="free_member==True">
<tr>
<h2 style="text-align:center;line-height: .1;">
</h2>
</tr>
<tr>
<h2 t-if="name"
style="text-align:left; margin-top: 0px;">
Name:
<span t-esc="name"/>
</h2>
</tr>
<tr>
<h2 t-if="phone" style="text-align:left; ">
Phone
No:
<span t-esc="phone" style="font-size: 25px !important; "/>
</h2>
</tr>
<tr>
<h2 t-if="function"
style="text-align:left;">
Job:
<span t-esc="function"/>
</h2>
</tr>
<br/>
<br/>
</tr>
<tr t-else="free_member==False">
<tr>
<h2 style="text-align:center;line-height: .1;">
</h2>
</tr>
<tr>
<h2 t-if="name"
style="text-align:left; margin-top: 0px; ">
Name:
<span t-esc="name"/>
</h2>
</tr>
<tr>
<h2 t-if="phone" style="text-align:left;">
Phone
No:
<span t-esc="phone"/>
</h2>
</tr>
<tr>
<h2 style="text-align:left;">Start Date:
<span t-esc="start_date"/>
</h2>
</tr>
<tr>
<h2 style="text-align:left;">End Date:
<span t-esc="end_date"/>
</h2>
</tr>
</tr>
</div>
</div>
</div>
<div style="border: 2px solid black; padding: 15px; height: 90%;">
<div class="session_2" style="width: 500px; ">
<tr>
<h2 style="text-align:left;">
<span t-esc="company_name"/>
</h2>
<h2 style="text-align:left;">
<span t-esc="company_address"/>,
<br/>
<span t-esc="city"/>,
<span t-esc="state"/>,
<span t-esc="country"/>
</h2>
<h2 style="text-align:left;">
Email:
<span t-esc="company_email"/>
</h2>
<h2 style="text-align:left;">
Contact:
<span t-esc="company_phone"/>
</h2>
<h2 style="text-align:left;">
<span t-esc="website"/>
</h2>
</tr>
</div>
</div>
</t>
</t>
</template>
</odoo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,548 @@
<div style="background-color: #714B67; height: 810px; width: 100%; padding: 15px; position: relative;">
<!-- TITLE BAR -->
<div class="d-flex align-items-center justify-content-between"
style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;">
<img src="assets/misc/cybrosys-logo.png" width="42" height="42" style="width: 42px; height: 42px;"/>
<div>
<div
style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Community
</div>
<div
style="color: #875A7B; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
<div
style="color: #017E84; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Odoo.sh
</div>
</div>
</div>
<!-- END OF TITLE BAR -->
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12">
<!-- APP HERO -->
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;">
Membership
Card</h1>
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">Print Membership
Card.</p>
<!-- END OF APP HERO -->
<img src="assets/screenshots/hero.gif" class="img-responsive"
style="width: 100%; margin-left: auto; margin-right: auto;"/>
</div>
</div>
</div>
</div>
<!-- NAVIGATION SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/compass.png"/>
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Explore This
Module</h2>
</div>
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;">
<div class="col-sm-12 col-md-6 my-3">
<a href="#overview">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn
more about this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#features">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
features of this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#screenshots">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
screenshots for this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
</div>
<!-- END OF NAVIGATION SECTION -->
<!-- OVERVIEW SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="overview">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pie-chart.png"/>
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Overview
</h2>
</div>
<div class="row" style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 py-4">
This module helps you to print Membership Card. If the partner having a membership product, a card with membership product will be printed or a card of free member will be printed.
</div>
</div>
<!-- END OF OVERVIEW SECTION -->
<!-- FEATURES SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="features">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/features.png"/>
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Features
</h2>
</div>
<div class="row" style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> Print Membership Card</span>
</div>
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> Free and Paid Membership Card</span>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Available in Odoo 15.0
Community and Enterprise.</span>
</div>
</div>
</div>
<!-- END OF FEATURES SECTION -->
<!-- SCREENSHOTS SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="screenshots">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pictures.png"/>
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Screenshots
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Membership Card
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Go to Members Module ->
Choose a Member.
Based on the condition Free or Paid this will allow you to print Membership Card. If it is Free,
Enable Free Member -> Action -> Print Membership Card. </p>
<img src="assets/screenshots/1.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Free Member Card
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Result of free
membership card which includes member details in front part and company details in other side. </p>
<img src="assets/screenshots/2.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Paid Member Card
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">If the partner is paid
member. Disable the 'Free Member'. Action -> Print Membership Card. </p>
<img src="assets/screenshots/3.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Result of paid
membership card </p>
<img src="assets/screenshots/4.png" class="img-thumbnail">
</div>
</div>
</div>
<!-- END OF SCREENSHOTS SECTION -->
<!-- RELATED PRODUCTS -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/categories.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Related
Products
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div id="demo1" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner" style="padding: 30px;">
<div class="carousel-item" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/whatsapp_redirect/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/1.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/auto_database_backup/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/2.gif">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/hide_menu_user/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/3.png">
</div>
</a>
</div>
</div>
<div class="carousel-item active" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/odoo_dynamic_dashboard/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/4.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/access_restriction_by_ip/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/5.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/whatsapp_mail_messaging/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/6.gif">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#demo1" data-slide="prev" style="width:35px; color:#000"> <span
class="carousel-control-prev-icon"><i class="fa fa-chevron-left" style="font-size:24px"></i></span>
</a> <a class="carousel-control-next" href="#demo1" data-slide="next" style="width:35px; color:#000">
<span class="carousel-control-next-icon"><i class="fa fa-chevron-right" style="font-size:24px"></i></span>
</a>
</div>
</div>
</div>
<!-- END OF RELATED PRODUCTS -->
<!-- OUR SERVICES -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/star.png"/>
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Our Services
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Licensing Consultancy</h6>
</div>
</div>
</div>
<!-- END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/corporate.png"/>
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Our
Industries
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/trading-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure
and
sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/pos-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/education-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/manufacturing-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/ecom-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/service-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/restaurant-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/hotel-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</div>
<!-- END OF OUR INDUSTRIES -->
<!-- SUPPORT -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/customer-support.png"/>
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Support
</h2>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #714B67; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/support.png" height="48" width="48" style="width: 42px; height: 42px;"/>
</div>
<div>
<h4>Need Help?</h4>
<p style="line-height: 100%;">Got questions or need help? Get in touch.</p>
<a href="mailto:odoo@cybrosys.com">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
odoo@cybrosys.com</p>
</a>
</div>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #2AC44D; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/whatsapp.png" height="52" width="52" style="width: 52px; height: 52px;"/>
</div>
<div>
<h4>WhatsApp</h4>
<p style="line-height: 100%;">Say hi to us on WhatsApp!</p>
<a href="https://api.whatsapp.com/send?phone=918606827707">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">+91 86068
27707</p>
</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 my-5 d-flex justify-content-center align-items-center">
<img src="assets/misc/logo.png" width="144" height="31"
style="width:144px; height: 31px; margin-top: 40px;"/>
</div>
</div>
</div>
<!-- END OF SUPPORT -->