@ -0,0 +1,49 @@ |
|||
.. 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 |
|||
|
|||
All in one WhatsApp Integration Odoo16 |
|||
====================================== |
|||
This module helps you to send a whatsapp message to your partners that are in sale order, |
|||
purchase order, invoice and bills, and deliver orders. |
|||
|
|||
Installation |
|||
============ |
|||
- www.odoo.com/documentation/16.0/setup/install.html |
|||
- pip install twilio |
|||
|
|||
Company |
|||
------- |
|||
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
|||
|
|||
License |
|||
------- |
|||
Affero General Public License, Version 3 (AGPL v3). |
|||
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
|||
|
|||
Credits |
|||
------- |
|||
Developer: (V16)- Raneesha M K, Jumana Jabin MP, Vishnu P |
|||
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 https://www.cybrosys.com |
|||
|
|||
Further information |
|||
=================== |
|||
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,25 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : 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 controllers |
|||
from . import models |
|||
from . import wizard |
@ -0,0 +1,57 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : 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': "All in one WhatsApp Integration Odoo16", |
|||
'version': '16.0.1.0.0', |
|||
'category': 'Extra Tools', |
|||
'summary': """WhatsApp Integration In Sale Order, Purchase Order, Delivery Order with Twilio and CloudAPI""", |
|||
'description': """WhatsApp, WhatsApp Odoo, whatsapp, WhatsApp Integration In Sale Order, Purchase Order, Delivery Order with Twilio and CloudAPI""", |
|||
'author': 'Cybrosys Techno Solutions', |
|||
'company': 'Cybrosys Techno Solutions', |
|||
'maintainer': 'Cybrosys Techno Solutions', |
|||
'website': "https://www.cybrosys.com", |
|||
'depends': ['base', 'web', 'sale', 'stock', 'purchase', 'account', |
|||
'contacts', 'website_livechat'], |
|||
'data': [ |
|||
'security/ir.model.access.csv', |
|||
'data/account_move_data.xml', |
|||
'data/purchase_order_data.xml', |
|||
'data/sale_order_data.xml', |
|||
'data/stock_picking_data.xml', |
|||
'views/sale_order_views.xml', |
|||
'views/purchase_order_views.xml', |
|||
'views/stock_picking_views.xml', |
|||
'views/account_move_views.xml', |
|||
'views/mail_template_views.xml', |
|||
'views/res_config_settings_views.xml', |
|||
'views/mail_channel_views.xml', |
|||
'wizard/send_whatsapp_message_views.xml', |
|||
], |
|||
'external_dependencies': { |
|||
'python': ['twilio'], |
|||
}, |
|||
'images': ['static/description/banner.png'], |
|||
'license': "AGPL-3", |
|||
'installable': True, |
|||
'auto_install': False, |
|||
'application': False, |
|||
} |
@ -0,0 +1,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by |
|||
# the Free Software Foundation, either version 3 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from . import all_in_one_whatsapp_integration |
@ -0,0 +1,92 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by |
|||
# the Free Software Foundation, either version 3 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from odoo import Command, http |
|||
from odoo.http import request |
|||
|
|||
|
|||
class Webhook(http.Controller): |
|||
""" Cloud api webhook controller """ |
|||
|
|||
@http.route('/whatsapp_message', type='http', auth='public', |
|||
methods=['GET', 'POST'], |
|||
csrf=False) |
|||
def get_webhook_url(self, **kwargs, ): |
|||
""" function create portal user and send message to live chat""" |
|||
if kwargs: |
|||
return (kwargs['hub.challenge']) |
|||
else: |
|||
active_user = request.env['res.users'].browse(request.uid) |
|||
data = request.get_json_data() |
|||
number = data['entry'][0]['changes'][0]['value'] |
|||
if number['contacts']: |
|||
profile = number['contacts'][0] |
|||
channel_partner_ids = [] |
|||
channel_partner_ids.append(active_user.partner_id.id) |
|||
to_partner = request.env['res.partner'].sudo().search([ |
|||
('phone', '=', str(number['metadata']['display_phone_number'])) |
|||
]) |
|||
if to_partner: |
|||
channel_partner_ids.append(to_partner.id) |
|||
contact = request.env['res.partner'].sudo().search([ |
|||
('name', '=', profile['profile']['name']), |
|||
('phone', '=', profile['wa_id']) |
|||
]) |
|||
if contact: |
|||
channel_partner_ids.append(contact.id) |
|||
else: |
|||
contact = request.env['res.users'].sudo().create({ |
|||
'name': profile['profile']['name'], |
|||
'company_id': active_user.company_id.id, |
|||
'login': profile['profile']['name'], |
|||
'groups_id': [ |
|||
Command.set( |
|||
[request.env.ref('base.group_portal').id])], |
|||
}).partner_id |
|||
contact.phone = profile['wa_id'] |
|||
channel_partner_ids.append(contact.id) |
|||
message_content = \ |
|||
data['entry'][0]['changes'][0]['value']['messages'][0] |
|||
channel = request.env['mail.channel'].sudo().search([ |
|||
('phone', '=', profile['wa_id']), |
|||
('channel_partner_ids', 'in', channel_partner_ids) |
|||
]) |
|||
if not channel: |
|||
channel = request.env['mail.channel'].sudo().create({ |
|||
'channel_partner_ids': [(4, contact.id), |
|||
(4, to_partner.id)], |
|||
'channel_type': 'livechat', |
|||
'name': profile['profile']['name'], |
|||
'phone': profile['wa_id'], |
|||
'livechat_operator_id': "3" |
|||
}) |
|||
uuid = channel.uuid |
|||
mail_channel = request.env["mail.channel"].sudo().search( |
|||
[('uuid', '=', uuid)], limit=1) |
|||
body = message_content['text']['body'] |
|||
x = mail_channel.with_context( |
|||
mail_create_nosubscribe=True).message_post( |
|||
author_id=contact.id, |
|||
body=body, |
|||
message_type='comment', |
|||
subtype_xmlid='mail.mt_comment' |
|||
) |
@ -0,0 +1,46 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<data noupdate="1"> |
|||
<!-- Whatsapp message mail template of account move --> |
|||
<record id="account_move_whatsapp_template" model="mail.template"> |
|||
<field name="name">Whatsapp Template for Invoice</field> |
|||
<field name="subject">Invoice Template</field> |
|||
<field name="model_id" ref="account.model_account_move"/> |
|||
<field name="is_invoice_template">True</field> |
|||
<field name="body_html"> |
|||
<![CDATA[<div style="font-family: Ubuntu, Arial, Verdana, sans-serif; font-size: 12px;"> |
|||
<p style="margin: 0px; padding: 0px; font-size: 13px;"> |
|||
<div> |
|||
Hello *<t t-out="object.partner_id.name or ''"></t>* |
|||
Greetings from *<t t-out="object.company_id.name or ' '"></t>* |
|||
</div> |
|||
<div> |
|||
Your invoice number *<t t-out="object.name"></t>* with amount *<t t-out="format_amount(object.amount_total, object.currency_id)"></t>* |
|||
from <t t-out="object.company_id.name"></t>. |
|||
</div> |
|||
<div> |
|||
<t t-if="object.payment_state in ('paid')"> |
|||
This invoice is already paid and Amount due is *<t t-out="format_amount(object.amount_residual, object.currency_id)"></t>* |
|||
</t> |
|||
<t t-else=""> |
|||
Please remit payment at your earliest convenience. Amount due is *<t t-out="format_amount(object.amount_residual, object.currency_id)"></t>* |
|||
</t> |
|||
</div> |
|||
The invoice date is <t t-out="object.invoice_date"></t> |
|||
<div> |
|||
Your order details are as follows: |
|||
<br> |
|||
<t t-foreach="object" t-as="each"> |
|||
<t t-foreach="each.invoice_line_ids" t-as="id"> |
|||
*Product: <t t-out="id.product_id.name"></t>* <br> |
|||
*Qty: <t t-out="id.quantity"></t>*<br> |
|||
*Price:<t t-out="id.price_unit"></t>*<br> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
If you have any questions, please feel free to contact us. |
|||
]]> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,58 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<data noupdate="1"> |
|||
<!--Whatsapp message mail template of purchase order --> |
|||
<record id="purchase_order_whatsapp_template" model="mail.template"> |
|||
<field name="name">Whatsapp Template for Purchase Order</field> |
|||
<field name="subject">Purchase Order Template</field> |
|||
<field name="model_id" ref="purchase.model_purchase_order"/> |
|||
<field name="is_purchase_template">True</field> |
|||
<field name="body_html"> |
|||
<![CDATA[<div style="font-family: Ubuntu, Arial, Verdana, sans-serif; font-size: 12px;"> |
|||
<p style="margin: 0px; padding: 0px; font-size: 13px;"> |
|||
<div> |
|||
Hello *<t t-out="object.partner_id.name or ''"></t>*, |
|||
Greetings from *<t t-out="object.company_id.name or ' '"></t>* |
|||
</div> |
|||
<t t-if="object.state in ('draft', 'sent')"> |
|||
Your Request For Quotation (RFQ) *<t t-out="object.name"></t>* with amount *<t t-out="format_amount(object.amount_total, object.currency_id)"></t>* is ready. |
|||
<div> |
|||
As per the planned date for receipt of products on <t t-out="object.date_planned"></t> |
|||
</div> |
|||
<div> |
|||
Quotation details are mentioned below: <br> |
|||
<t t-foreach="object" t-as="each"> |
|||
<t t-foreach="each.order_line" t-as="id"> |
|||
*Product: <t t-out="id.product_id.name"></t>* <br> |
|||
*Qty: <t t-out="id.product_qty"></t>*<br> |
|||
*Price:<t t-out="id.price_subtotal"></t>*<br> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
<t t-else=""> |
|||
<div> |
|||
Your Purchase Order Number *<t t-out="object.name"></t>* with amount *<t t-out="format_amount(object.amount_total, object.currency_id)"></t>* is Confirmed. |
|||
</div> |
|||
<div> |
|||
As per you RFQ Order confirmation date and time is <t t-out="object.date_approve"></t> |
|||
</div> |
|||
<div> |
|||
Order details are mentioned below: <br> |
|||
<t t-foreach="object" t-as="each"> |
|||
<t t-foreach="each.order_line" t-as="id"> |
|||
*Product: <t t-out="id.product_id.name"></t>* <br> |
|||
*Qty: <t t-out="id.product_qty"></t>*<br> |
|||
*Price:<t t-out="id.price_subtotal"></t>*<br> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
<div> |
|||
If you require any further information, feel free to contact me. |
|||
</div> |
|||
]]> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,56 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<data noupdate="1"> |
|||
<!--Whatsapp message mail template of sale order --> |
|||
<record id="sale_order_whatsapp_template" model="mail.template"> |
|||
<field name="name">Whatsapp Template for Sale Order</field> |
|||
<field name="subject">Sales Order Template</field> |
|||
<field name="model_id" ref="sale.model_sale_order"/> |
|||
<field name="is_sale_template">True</field> |
|||
<field name="body_html"><![CDATA[<div style="font-family: Ubuntu, Arial, Verdana, sans-serif; font-size: 14px;"> |
|||
<div> |
|||
Hello *<t t-out="object.partner_id.name or ' '"></t>*, <br> |
|||
Greetings from *<t t-out="object.company_id.name or ' '"></t>* |
|||
</div> |
|||
<t t-if="object.state in ('draft', 'sent')"> |
|||
Your Sale Order Quotation *<t t-out="object.name or ' '"></t>* with amount *<t t-out="format_amount(object.amount_total, object.currency_id)"></t>* is ready. |
|||
<div> |
|||
As per your quotation the date and time of the order is "<t t-out="object.date_order"></t>" |
|||
</div> |
|||
<div> |
|||
Quotation details are mentioned below: <br> |
|||
<t t-foreach="object" t-as="orders"> |
|||
<t t-foreach="orders.order_line" t-as="order_id"> |
|||
*Product: <t t-out="order_id.product_id.name"></t>* <br> |
|||
*Quantity: <t t-out="order_id.product_uom_qty"></t>*<br> |
|||
*Price:<t t-out="order_id.price_subtotal"></t>*<br> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
<t t-else=""> |
|||
<div> |
|||
Your Sale Order Number *<t t-out="object.name or ''"></t>* with amount *<t t-out="format_amount(object.amount_total, object.currency_id)"></t>* is Confirmed. |
|||
</div> |
|||
<div> |
|||
As per your quotation your order date and time of the order is "<t t-out="object.date_order"></t>" |
|||
</div> |
|||
<div> |
|||
Your order details are mentioned below: <br> |
|||
<t t-foreach="object" t-as="orders"> |
|||
<t t-foreach="orders.order_line" t-as="order_id"> |
|||
*Product: <t t-out="order_id.product_id.name"></t>* <br> |
|||
*Quantity: <t t-out="order_id.product_uom_qty"></t>*<br> |
|||
*Price:<t t-out="order_id.price_subtotal"></t>*<br> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
<div> |
|||
If you require any further information, feel free to contact me. |
|||
</div> |
|||
</t> |
|||
]]> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,73 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<data noupdate="1"> |
|||
<!--Whatsapp message mail template of stock picking --> |
|||
<record id="stock_picking_whatsapp_template" model="mail.template"> |
|||
<field name="name">Whatsapp Template for Delivery</field> |
|||
<field name="subject">Inventory Template</field> |
|||
<field name="model_id" ref="stock.model_stock_picking"/> |
|||
<field name="is_delivery_template">True</field> |
|||
<field name="body_html"><![CDATA[<div style="font-family: Ubuntu, Arial, Verdana, sans-serif; font-size: 12px;"> |
|||
<p style="margin: 0px; padding: 0px; font-size: 13px;"> |
|||
<div> |
|||
Hello *<t t-out="object.partner_id.name or ''"></t>*, |
|||
</div> |
|||
<div> |
|||
<t t-if="object.state in ('draft')"> |
|||
We have received your order *<t t-out="object.name"></t>*. It will be shipped soon |
|||
<div> |
|||
Order details are as follows: <br> |
|||
<t t-foreach="object" t-as="each"> |
|||
<t t-foreach="each.move_ids_without_package" t-as="id"> |
|||
*Product: <t t-out="id.product_id.name"></t>* <br> |
|||
*Qty: <t t-out="id.product_uom_qty"></t>*<br> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
<t t-if="object.state in ('assigned')"> |
|||
Your order *<t t-out="object.name"></t>* is ready. It will be shipped soon |
|||
<div> |
|||
Order details are as follows: <br> |
|||
<t t-foreach="object" t-as="each"> |
|||
<t t-foreach="each.move_ids_without_package" t-as="id"> |
|||
*Product: <t t-out="id.product_id.name"></t>* <br> |
|||
*Qty: <t t-out="id.product_uom_qty"></t>*<br> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
<t t-if="object.state in ('confirmed')"> |
|||
Your order *<t t-out="object.name"></t>* is ready. It will be shipped soon |
|||
<div> |
|||
Order details are as follows: <br> |
|||
<t t-foreach="object" t-as="each"> |
|||
<t t-foreach="each.move_ids_without_package" t-as="id"> |
|||
*Product: <t t-out="id.product_id.name"></t>* <br> |
|||
*Qty: <t t-out="id.product_uom_qty"></t>*<br> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
<t t-if="object.state in ('done')"> |
|||
Your order *<t t-out="object.name"></t>* is shipped. |
|||
<div> |
|||
Order details are as follows: <br> |
|||
<t t-foreach="object" t-as="each"> |
|||
<t t-foreach="each.move_ids_without_package" t-as="id"> |
|||
*Product: <t t-out="id.product_id.name"></t>* <br> |
|||
*Qty: <t t-out="id.quantity_done"></t>*<br> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
</div> |
|||
<div> |
|||
If you have any questions, please feel free to contact us. |
|||
</div> |
|||
</p> |
|||
]]> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,6 @@ |
|||
## Module <whatsapp_integration_odoo> |
|||
|
|||
#### 26.10.2023 |
|||
#### Version 16.0.1.0.0 |
|||
#### ADD |
|||
- Initial Commit for All in one Whatsapp |
@ -0,0 +1,29 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : 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 account_move |
|||
from . import mail_channel |
|||
from . import mail_message |
|||
from . import mail_template |
|||
from . import purchase_order |
|||
from . import res_config_settings |
|||
from . import sale_order |
|||
from . import stock_picking |
@ -0,0 +1,78 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by |
|||
# the Free Software Foundation, either version 3 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
import base64 |
|||
import html2text |
|||
from odoo import models, _ |
|||
from odoo.exceptions import ValidationError |
|||
|
|||
|
|||
class AccountMove(models.Model): |
|||
"""Inherited the module for adding a button that helps to send WhatsApp |
|||
message to the customer. """ |
|||
_inherit = 'account.move' |
|||
|
|||
def action_send_by_whatsapp(self): |
|||
""" |
|||
This method is invoked when the 'send_by_whatsapp' button is clicked. |
|||
It opens a wizard containing the message to be sent to the WhatsApp |
|||
web page. """ |
|||
if not self.partner_id.mobile: |
|||
raise ValidationError( |
|||
_('Add a WhatsApp mobile number to the sale order partner!')) |
|||
if not self.partner_id.mobile.startswith('+'): |
|||
raise ValidationError( |
|||
_('Please add a valid mobile number along with a valid' |
|||
' country code!')) |
|||
twilio_whatsapp = self.env['ir.config_parameter'].sudo().get_param( |
|||
'all_in_one_whatsapp_integration.twilio_whatsapp') |
|||
if not twilio_whatsapp.startswith('+'): |
|||
raise ValidationError( |
|||
_('Please add a valid Twilio mobile number along with "+".')) |
|||
template_id = self.env.ref( |
|||
'all_in_one_whatsapp_integration.account_move_whatsapp_template').id |
|||
mail_template = self.env['mail.template'].browse(template_id) |
|||
mail_template_values = mail_template.with_context( |
|||
tpl_partners_only=True).generate_email( |
|||
[self.id], fields=['body_html']) |
|||
body_html = mail_template_values[self.id].pop('body_html', '') |
|||
whatsapp_message = html2text.html2text(body_html) |
|||
report = self.env['ir.actions.report']._render_qweb_pdf( |
|||
'account.account_invoices', self.id) |
|||
report_attachment = self.env['ir.attachment'].sudo().create({ |
|||
'name': 'Invoice Report', |
|||
'type': 'binary', |
|||
'datas': base64.b64encode(report[0]), |
|||
'store_fname': 'Invoice Report.pdf', |
|||
'mimetype': 'application/pdf', |
|||
'res_model': 'account.move', |
|||
}) |
|||
return { |
|||
'type': 'ir.actions.act_window', |
|||
'name': _('WhatsApp Message'), |
|||
'res_model': 'send.whatsapp.message', |
|||
'target': 'new', |
|||
'view_mode': 'form', |
|||
'view_type': 'form', |
|||
'context': {'default_whatsapp_message': whatsapp_message, |
|||
'default_attachment_ids': [(4, report_attachment.id)]}, |
|||
} |
@ -0,0 +1,32 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by |
|||
# the Free Software Foundation, either version 3 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class MailChannel(models.Model): |
|||
"""This class extends the base 'mail.channel' model in Odoo to include a |
|||
'phone' field for storing the phone number associated with the |
|||
communication channel.""" |
|||
_inherit = 'mail.channel' |
|||
|
|||
phone = fields.Char(string='Phone', help='Phone') |
@ -0,0 +1,66 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by |
|||
# the Free Software Foundation, either version 3 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# 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 for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
import http.client |
|||
import json |
|||
from odoo import api, models |
|||
|
|||
|
|||
class MailMessage(models.Model): |
|||
"""This class extends the base 'mail.message' model in Odoo to include |
|||
functionality for sending WhatsApp messages using Facebook Graph API. |
|||
""" |
|||
_inherit = 'mail.message' |
|||
|
|||
@api.model_create_multi |
|||
def create(self, values_list): |
|||
"""This method creates a new mail message and then sends the message's |
|||
body as a WhatsApp message using the Facebook Graph API.""" |
|||
bearer_token = self.env['ir.config_parameter'].sudo().get_param( |
|||
'all_in_one_whatsapp_integration.bearer_token') |
|||
whatsapp_no = self.env['ir.config_parameter'].sudo().get_param( |
|||
'all_in_one_whatsapp_integration.whatsapp_no') |
|||
if bearer_token and whatsapp_no and values_list[0]['model'] == 'mail.channel': |
|||
if values_list[0]['email_from']: |
|||
mail_channel = self.env['mail.channel'].browse( |
|||
values_list[0]['res_id']) |
|||
if mail_channel: |
|||
conn = http.client.HTTPSConnection("graph.facebook.com") |
|||
payload = json.dumps({ |
|||
"messaging_product": "whatsapp", |
|||
"recipient_type": "individual", |
|||
"to": mail_channel.phone, |
|||
"type": 'text', |
|||
"text": { |
|||
"preview_url": False, |
|||
"body": values_list[0]['body'] |
|||
} |
|||
}) |
|||
headers = { |
|||
'Content-Type': 'application/json', |
|||
'Authorization': f'Bearer {bearer_token}' |
|||
} |
|||
conn.request("POST", f"/v17.0/{whatsapp_no}/messages", |
|||
payload, |
|||
headers) |
|||
response = conn.getresponse() |
|||
return super(MailMessage, self).create(values_list) |
@ -0,0 +1,45 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : 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 |
|||
|
|||
|
|||
class MailTemplate(models.Model): |
|||
"""Inherited this model for adding some fields that help to check the |
|||
message template is a delivery, invoice, purchase, or sale order |
|||
template """ |
|||
_inherit = 'mail.template' |
|||
|
|||
is_delivery_template = fields.Boolean(string='Delivery Template', |
|||
help="To check the message template" |
|||
" for sending delivery " |
|||
"to whatsapp") |
|||
is_invoice_template = fields.Boolean(string='Invoice Template', |
|||
help="To check the message template " |
|||
"for sending delivery " |
|||
"to whatsapp") |
|||
is_purchase_template = fields.Boolean(string="Purchase Template", |
|||
help="To check the message template " |
|||
"sending purchase order to" |
|||
" whatsapp") |
|||
is_sale_template = fields.Boolean(string="Sale Template", |
|||
help="To check the message template for" |
|||
"sending sale order to whatsapp") |
@ -0,0 +1,80 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : 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/>. |
|||
# |
|||
############################################################################### |
|||
import base64 |
|||
import html2text |
|||
from odoo import models, _ |
|||
from odoo.exceptions import ValidationError |
|||
|
|||
|
|||
class PurchaseOrder(models.Model): |
|||
"""Inherited the module for adding a button that helps to send whatsapp |
|||
message to the customer """ |
|||
_inherit = "purchase.order" |
|||
|
|||
def action_send_by_whatsapp(self): |
|||
""" When you click the send_by_whatsapp button, it will open a wizard |
|||
that contain the message to send to the whatsapp web page. """ |
|||
if not self.partner_id.mobile: |
|||
raise ValidationError(_('Add whatsapp mobile number in ' |
|||
'sale order partner!')) |
|||
if not self.partner_id.mobile[0] == "+": |
|||
raise ValidationError(_('Please add a valid mobile' |
|||
'number along with a valid country code!')) |
|||
twilio_whatsapp = (self.env["ir.config_parameter"].sudo().get_param |
|||
("all_in_one_whatsapp_integration.twilio_whatsapp")) |
|||
if not twilio_whatsapp: |
|||
raise ValidationError(_("Please add your valid twilio" |
|||
"whatsapp number in settings")) |
|||
if twilio_whatsapp[0] != "+": |
|||
raise ValidationError(_("Please add a valid " |
|||
"twilio mobile number along with +")) |
|||
template_id = self.env.ref("all_in_one_whatsapp_integration." |
|||
"purchase_order_whatsapp_template").id |
|||
mail_template_values = ( |
|||
self.env["mail.template"] |
|||
.with_context(tpl_partners_only=True) |
|||
.browse(template_id) |
|||
.generate_email([self.id], fields=["body_html"])) |
|||
body_html = dict(mail_template_values)[self.id].pop("body_html", "") |
|||
whatsapp_message = html2text.html2text(body_html) |
|||
report = self.env["ir.actions.report"]._render_qweb_pdf( |
|||
"purchase.action_report_purchase_order", self.id) |
|||
report_attachment = self.env["ir.attachment"].sudo().create({ |
|||
"name": "Purchase Report", |
|||
"type": "binary", |
|||
"datas": base64.b64encode(report[0]), |
|||
"store_fname": base64.b64encode(report[0]), |
|||
"mimetype": "application/pdf", |
|||
"res_model": "purchase.order", |
|||
}) |
|||
return { |
|||
"type": "ir.actions.act_window", |
|||
"name": _("Whatsapp Message"), |
|||
"res_model": "send.whatsapp.message", |
|||
"target": "new", |
|||
"view_mode": "form", |
|||
"view_type": "form", |
|||
"context": { |
|||
"default_whatsapp_message": whatsapp_message, |
|||
"default_attachment_ids": [(4, report_attachment.id)], |
|||
}, |
|||
} |
@ -0,0 +1,54 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : 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 |
|||
|
|||
|
|||
class ResConfigSettings(models.TransientModel): |
|||
""" Inherited this module is to add fields for WhatsApp's |
|||
message-sending authentication """ |
|||
_inherit = "res.config.settings" |
|||
|
|||
account_sid = fields.Char(string="Account SID", |
|||
config_parameter='all_in_one_whatsapp_integration.' |
|||
'account_sid', |
|||
help="Account SID of twilio account", ) |
|||
auth_token = fields.Char(string="Auth Token", |
|||
config_parameter='all_in_one_whatsapp_integration.' |
|||
'auth_token', |
|||
help="Auth Token of twilio account") |
|||
twilio_whatsapp = fields.Char(string="Twilio Whatsapp Number", |
|||
config_parameter='all_in_one_whatsapp_integration' |
|||
'.twilio_whatsapp', |
|||
help="Whatsapp number of twilio account") |
|||
bearer_token = fields.Char(string="Whatsapp Access Token", |
|||
help="Authorization Token of Whatsapp Cloud " |
|||
"API", |
|||
config_parameter='all_in_one_whatsapp_integration.' |
|||
'bearer_token', ) |
|||
whatsapp_no = fields.Char(string="Phone number ID", |
|||
help="Phone Number ID of Whatsapp Cloud API", |
|||
config_parameter='all_in_one_whatsapp_integration.' |
|||
'whatsapp_no', ) |
|||
whatsapp_business = fields.Char(help="Business ID of Whatsapp Cloud API", |
|||
string="Whatsapp Business Account ID", |
|||
config_parameter='whatsapp_integration_' |
|||
'odoo.whatsapp_business', ) |
@ -0,0 +1,80 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : 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/>. |
|||
# |
|||
############################################################################### |
|||
import base64 |
|||
import html2text |
|||
from odoo import models, _ |
|||
from odoo.exceptions import ValidationError |
|||
|
|||
|
|||
class SaleOrder(models.Model): |
|||
"""Inherited the module for adding a button that helps to send whatsapp |
|||
message to the customer """ |
|||
_inherit = "sale.order" |
|||
|
|||
def action_send_by_whatsapp(self): |
|||
"""When you click the send_by_whatsapp button, it will open a wizard |
|||
that contain the message to send to the whatsapp web page.""" |
|||
if not self.partner_id.mobile: |
|||
raise ValidationError(_('Add whatsapp mobile number in ' |
|||
'sale order partner!')) |
|||
if not self.partner_id.mobile[0] == "+": |
|||
raise ValidationError(_('Please add a valid mobile' |
|||
'number along with a valid country code!')) |
|||
twilio_whatsapp = (self.env["ir.config_parameter"].sudo().get_param |
|||
("all_in_one_whatsapp_integration.twilio_whatsapp")) |
|||
if not twilio_whatsapp: |
|||
raise ValidationError(_("Please add your valid twilio" |
|||
"whatsapp number in settings")) |
|||
if twilio_whatsapp[0] != "+": |
|||
raise ValidationError(_("Please add a valid " |
|||
"twilio mobile number along with +")) |
|||
template_id = self.env.ref("all_in_one_whatsapp_integration." |
|||
"sale_order_whatsapp_template").id |
|||
mail_template_values = (self.env["mail.template"]. |
|||
with_context(tpl_partners_only=True). |
|||
browse(template_id).generate_email |
|||
([self.id], fields=["body_html"])) |
|||
body_html = dict(mail_template_values)[self.id].pop("body_html", "") |
|||
whatsapp_message = html2text.html2text(body_html) |
|||
report = self.env["ir.actions.report"]._render_qweb_pdf( |
|||
"sale.action_report_saleorder", self.id) |
|||
report_attachment = self.env["ir.attachment"].sudo().create({ |
|||
"name": "Sale Report", |
|||
"type": "binary", |
|||
"datas": base64.b64encode(report[0]), |
|||
"store_fname": base64.b64encode(report[0]), |
|||
"mimetype": "application/pdf", |
|||
"res_model": "sale.order", |
|||
}) |
|||
return { |
|||
"type": "ir.actions.act_window", |
|||
"name": _("Whatsapp Message"), |
|||
"res_model": "send.whatsapp.message", |
|||
"target": "new", |
|||
"view_mode": "form", |
|||
"view_type": "form", |
|||
"context": { |
|||
"default_whatsapp_message": whatsapp_message, |
|||
"default_attachment_ids": [(4, report_attachment.id)], |
|||
"default_attachment_id": report_attachment.id, |
|||
}, |
|||
} |
@ -0,0 +1,77 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Cybrosys Techno Solutions (Contact : 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/>. |
|||
# |
|||
############################################################################### |
|||
import base64 |
|||
import html2text |
|||
from odoo import models, _ |
|||
from odoo.exceptions import ValidationError |
|||
|
|||
|
|||
class StockPicking(models.Model): |
|||
"""Inherited the module for adding a button that helps to send whatsapp |
|||
message to the customer """ |
|||
_inherit = 'stock.picking' |
|||
|
|||
def action_send_by_whatsapp(self): |
|||
"""When you click the send_by_whatsapp button, it will open a wizard |
|||
that contain the message to send to the whatsapp web page.""" |
|||
if not self.partner_id.mobile: |
|||
raise ValidationError(_( |
|||
'Add whatsapp mobile number in sale order partner!')) |
|||
if not self.partner_id.mobile[0] == '+': |
|||
raise ValidationError(_( |
|||
'Please add a valid mobile number along with a valid ' |
|||
'country code!')) |
|||
twilio_whatsapp = (self.env['ir.config_parameter'] |
|||
.sudo().get_param('all_in_one_whatsapp_integration.' |
|||
'twilio_whatsapp')) |
|||
if twilio_whatsapp[0] != '+': |
|||
raise ValidationError(_( |
|||
'Please add a valid twilio mobile number along with +')) |
|||
template_id = self.env.ref('all_in_one_whatsapp_integration.' |
|||
'stock_picking_whatsapp_template').id |
|||
mail_template_values = (self.env['mail.template'] |
|||
.with_context(tpl_partners_only=True). |
|||
browse(template_id).generate_email |
|||
([self.id], fields=['body_html'])) |
|||
body_html = dict(mail_template_values)[self.id].pop('body_html', '') |
|||
whatsapp_message = html2text.html2text(body_html) |
|||
report = (self.env['ir.actions.report']._render_qweb_pdf |
|||
('stock.action_report_delivery', self.id)) |
|||
report_attachment = self.env['ir.attachment'].sudo().create({ |
|||
'name': 'Delivery Report', |
|||
'type': 'binary', |
|||
'datas': base64.b64encode(report[0]), |
|||
'store_fname': base64.b64encode(report[0]), |
|||
'mimetype': 'application/pdf', |
|||
'res_model': 'stock.picking', |
|||
}) |
|||
return { |
|||
'type': 'ir.actions.act_window', |
|||
'name': _('Whatsapp Message'), |
|||
'res_model': 'send.whatsapp.message', |
|||
'target': 'new', |
|||
'view_mode': 'form', |
|||
'view_type': 'form', |
|||
'context': {'default_whatsapp_message': whatsapp_message, |
|||
'default_attachment_ids': [(4, |
|||
report_attachment.id)]}, |
|||
} |
|
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 173 KiB |
After Width: | Height: | Size: 457 KiB |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 119 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 180 KiB |
After Width: | Height: | Size: 155 KiB |
After Width: | Height: | Size: 168 KiB |
After Width: | Height: | Size: 469 KiB |
After Width: | Height: | Size: 169 KiB |
After Width: | Height: | Size: 468 KiB |
After Width: | Height: | Size: 123 KiB |
After Width: | Height: | Size: 133 KiB |
After Width: | Height: | Size: 496 KiB |
After Width: | Height: | Size: 193 KiB |
After Width: | Height: | Size: 164 KiB |
After Width: | Height: | Size: 149 KiB |
After Width: | Height: | Size: 170 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 127 KiB |
After Width: | Height: | Size: 125 KiB |
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 119 KiB |
After Width: | Height: | Size: 242 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 226 KiB |
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 111 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 203 KiB |
After Width: | Height: | Size: 186 KiB |
After Width: | Height: | Size: 175 KiB |
After Width: | Height: | Size: 130 KiB |
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 1.3 MiB |