diff --git a/README.md b/README.md index 8b10e6960..6864725ce 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# odex25-standard-moduless +# odex25-standard-modules This Repo contains general standard modules for all projects. diff --git a/odex25_sales/bi_multi_product_selection/LICENSE b/odex25_sales/bi_multi_product_selection/LICENSE new file mode 100644 index 000000000..de7bcc64e --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/LICENSE @@ -0,0 +1,28 @@ +Odoo Proprietary License v1.0 + +This software and associated files (the "Software") may only be used (executed, +modified, executed after modifications) if you have purchased a valid license +from the authors, typically via Odoo Apps, or if you have received a written +agreement from the authors of the Software (see the COPYRIGHT file). + +You may develop Odoo modules that use the Software as a library (typically +by depending on it, importing it and using its resources), but without copying +any source code or material from the Software. You may distribute those +modules under the license of your choice, provided that this license is +compatible with the terms of the Odoo Proprietary License (For example: +LGPL, MIT, or proprietary licenses similar to this one). + +It is forbidden to publish, distribute, sublicense, or sell copies of the Software +or modified copies of the Software. + +The above copyright notice and this permission notice must be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/odex25_sales/bi_multi_product_selection/ReadME.txt b/odex25_sales/bi_multi_product_selection/ReadME.txt new file mode 100644 index 000000000..e69de29bb diff --git a/odex25_sales/bi_multi_product_selection/__init__.py b/odex25_sales/bi_multi_product_selection/__init__.py new file mode 100644 index 000000000..be7b3ddf9 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from . import models +from . import wizard \ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/__manifest__.py b/odex25_sales/bi_multi_product_selection/__manifest__.py new file mode 100644 index 000000000..3c9efd52b --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/__manifest__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. +{ + "name" : "Multi Product Selection in Sales & Purchase", + "version" : "14.0.0.0", + "category" : "Odex25-Sales/Odex25-Sales", + "summary": 'Multiple product selection sales multi products selection purchase select multiple products on delivery order line add multiple products invoice line sales order add multi products purchase order multi product selection sales and purchase multiple products', + "description": """ + + Multi Product Selection Odoo App helps users to select multiple product in sales order line, purchase order line, delivery order line and an invoice line. User can add multiple product in order line with single click and only in draft stage. + + """, + "author": "BrowseInfo", + "website" : "https://www.browseinfo.com", + "depends" : ['base','sale_management','purchase','stock'], + "data": [ + 'security/ir.model.access.csv', + 'views/sale_order_view.xml', + 'views/purchase_order_view.xml', + 'views/account_move_view.xml', + 'views/stock_picking_view.xml', + 'wizard/purchase_order_wizard_view.xml', + 'wizard/sale_order_wizard_view.xml', + 'wizard/account_move_wizard_view.xml', + 'wizard/stock_picking_view.xml', + ], + 'license':'OPL-1', + 'installable': True, + 'auto_install': False, + 'live_test_url':'https://youtu.be/9_ccgoFoTBs', + "images":['static/description/Multi-Product-Selection.gif'], +} diff --git a/odex25_sales/bi_multi_product_selection/models/__init__.py b/odex25_sales/bi_multi_product_selection/models/__init__.py new file mode 100644 index 000000000..b8af75c60 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from . import multi_product_selection diff --git a/odex25_sales/bi_multi_product_selection/models/multi_product_selection.py b/odex25_sales/bi_multi_product_selection/models/multi_product_selection.py new file mode 100644 index 000000000..ae7fe3f3c --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/models/multi_product_selection.py @@ -0,0 +1,86 @@ +from odoo import _, api, fields, models + +class SaleOder(models.Model): + + _inherit = 'sale.order' + + product_ids = fields.Many2many('product.product',string="Select Product", required=True) + partner_id = fields.Many2one(string='Customer', comodel_name='res.partner', ondelete='restrict',required=True) + + def sale_order_select_prodcut(self): + wizard = self.env['sale.order.wizard'].create({ + 'product_ids': self.product_ids.name }) + + return { + 'name': _('Select Product'), + 'type': 'ir.actions.act_window', + 'res_model': 'sale.order.wizard', + 'view_mode': 'form', + 'res_id': wizard.id, + 'target': 'new', + 'context': {'default_active_id': self.id}, + } + +class PurhcaseOrder(models.Model): + + _inherit = 'purchase.order' + + product_ids = fields.Many2many('product.product',string="Select Product",required=True) + partner_id = fields.Many2one(string='Customer', comodel_name='res.partner', ondelete='restrict') + + def purchase_order_select_prodcut(self): + wizard = self.env['purchase.order.wizard'].create({ + 'product_ids': self.product_ids.name }) + + return { + 'name': _('Select Product'), + 'type': 'ir.actions.act_window', + 'res_model': 'purchase.order.wizard', + 'view_mode': 'form', + 'res_id': wizard.id, + 'target': 'new' + } + +class AccountMove(models.Model): + + _inherit = 'account.move' + + product_ids = fields.Many2many('product.product',string="Select Product",required=True) + partner_id = fields.Many2one(string='Customer', comodel_name='res.partner', ondelete='restrict') + + def invoice_select_prodcut(self): + wizard = self.env['account.move.wizard'].create({ + 'product_ids': self.product_ids.name }) + + return { + 'name': _('Select Product'), + 'type': 'ir.actions.act_window', + 'res_model': 'account.move.wizard', + 'view_mode': 'form', + 'res_id': wizard.id, + 'target': 'new' + } + +class StockPicking(models.Model): + + _inherit = 'stock.picking' + + product_ids = fields.Many2many('product.product',string="Select Product", required=True) + partner_id = fields.Many2one(string='Customer', comodel_name='res.partner', ondelete='restrict',required=True) + + def stock_picking_select_prodcut(self): + wizard = self.env['stock.picking.wizard'].create({ + 'product_ids': self.product_ids.name }) + + return { + 'name': _('Select Product'), + 'type': 'ir.actions.act_window', + 'res_model': 'stock.picking.wizard', + 'view_mode': 'form', + 'res_id': wizard.id, + 'target': 'new', + 'context': {'default_active_id': self.id}, + } + + + diff --git a/odex25_sales/bi_multi_product_selection/security/ir.model.access.csv b/odex25_sales/bi_multi_product_selection/security/ir.model.access.csv new file mode 100644 index 000000000..3cad85f99 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_sale_order_wizard,access_sale_order_wizard,model_sale_order_wizard,base.group_user,1,1,1,1 +access_purchase_order_wizard,access_purchase_order_wizard,model_purchase_order_wizard,base.group_user,1,1,1,1 +access_account_move_wizard,access_account_move_wizard,model_account_move_wizard,base.group_user,1,1,1,1 +access_stock_picking_wizard,access_stock_picking_wizard,model_stock_picking_wizard,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/static/description/10_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/10_multi_product.png new file mode 100644 index 000000000..d026abc8e Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/10_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/11_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/11_multi_product.png new file mode 100644 index 000000000..d23597aa5 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/11_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/12_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/12_multi_product.png new file mode 100644 index 000000000..3329a4db7 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/12_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/13_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/13_multi_product.png new file mode 100644 index 000000000..073e84dd1 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/13_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/14_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/14_multi_product.png new file mode 100644 index 000000000..381d05740 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/14_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/1_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/1_multi_product.png new file mode 100644 index 000000000..e89653e57 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/1_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/2_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/2_multi_product.png new file mode 100644 index 000000000..8445f2567 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/2_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/3_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/3_multi_product.png new file mode 100644 index 000000000..fe39a19b7 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/3_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/4_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/4_multi_product.png new file mode 100644 index 000000000..6a9e14dba Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/4_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/5_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/5_multi_product.png new file mode 100644 index 000000000..e629b6569 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/5_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/6_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/6_multi_product.png new file mode 100644 index 000000000..0862b9e4b Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/6_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/7_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/7_multi_product.png new file mode 100644 index 000000000..47abeaecb Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/7_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/8_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/8_multi_product.png new file mode 100644 index 000000000..1ae3b2c49 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/8_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/9_multi_product.png b/odex25_sales/bi_multi_product_selection/static/description/9_multi_product.png new file mode 100644 index 000000000..897332bbe Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/9_multi_product.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/Multi-Product-Selection.gif b/odex25_sales/bi_multi_product_selection/static/description/Multi-Product-Selection.gif new file mode 100644 index 000000000..2c421538e Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/Multi-Product-Selection.gif differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/bi_logo.png b/odex25_sales/bi_multi_product_selection/static/description/bi_logo.png new file mode 100644 index 000000000..e5d60b273 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/bi_logo.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/demanded/all_in_one_pos.png b/odex25_sales/bi_multi_product_selection/static/description/demanded/all_in_one_pos.png new file mode 100644 index 000000000..e51fc57b3 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/demanded/all_in_one_pos.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/demanded/bi_generic_import.png b/odex25_sales/bi_multi_product_selection/static/description/demanded/bi_generic_import.png new file mode 100644 index 000000000..785b6579f Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/demanded/bi_generic_import.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/demanded/branch.png b/odex25_sales/bi_multi_product_selection/static/description/demanded/branch.png new file mode 100644 index 000000000..70209a610 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/demanded/branch.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/demanded/customer_overdue.png b/odex25_sales/bi_multi_product_selection/static/description/demanded/customer_overdue.png new file mode 100644 index 000000000..b9efae230 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/demanded/customer_overdue.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/demanded/generic_excel_reports.png b/odex25_sales/bi_multi_product_selection/static/description/demanded/generic_excel_reports.png new file mode 100644 index 000000000..4800329d7 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/demanded/generic_excel_reports.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/demanded/sale_commision.png b/odex25_sales/bi_multi_product_selection/static/description/demanded/sale_commision.png new file mode 100644 index 000000000..145289f73 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/demanded/sale_commision.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/features/1_features.png b/odex25_sales/bi_multi_product_selection/static/description/features/1_features.png new file mode 100644 index 000000000..96fe2ddb6 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/features/1_features.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/features/2_features.png b/odex25_sales/bi_multi_product_selection/static/description/features/2_features.png new file mode 100644 index 000000000..52f808d4f Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/features/2_features.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/features/3_feature.png b/odex25_sales/bi_multi_product_selection/static/description/features/3_feature.png new file mode 100644 index 000000000..e39314f60 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/features/3_feature.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/features/4_feature.png b/odex25_sales/bi_multi_product_selection/static/description/features/4_feature.png new file mode 100644 index 000000000..f133e1c73 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/features/4_feature.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/icon.png b/odex25_sales/bi_multi_product_selection/static/description/icon.png new file mode 100644 index 000000000..da1092e28 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/icon.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/index.html b/odex25_sales/bi_multi_product_selection/static/description/index.html new file mode 100644 index 000000000..f929f91a8 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/static/description/index.html @@ -0,0 +1,375 @@ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+

+ Select Multiple Products in Sales and Purchase Orders +

+

+ Sales Order Multi Product Selection Odoo Apps +

+

+ Multiple Product Selection in Purchase Order Odoo Apps +

+

+ Sales & Purchase Multi Product Selection Odoo Apps +

+

+ Multi Product Selection Odoo App allows users to work with sales orders, purchase orders, delivery orders, and invoices. This app simplifies selecting multiple products, streamlining the workflow, and saving valuable time. Users can conveniently add multiple products to order lines with a single click. Still, it's important to note that this feature is available only during the draft stage of document creation. +

+
+
+
+ +
+
+
+

Features

+
+
+
+
+
+ +
+
+

Add Multiple Products on Sale Order Line

+ User can add multiple products on sale order line. +
+
+
+
+
+
+ +
+
+

Add Multiple Product on Purchase Order Line

+ User can add multiple products on purchase order line. +
+
+
+
+
+
+
+
+ +
+
+

Add Multiple Products on Delivery Order Line

+ User can add multiple products on delivery order line. +
+
+
+
+
+
+ +
+
+

Add Multiple Product on Invoice Line

+ User can add multiple products on an invoice line. +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+

Add Multiple Products on Sale Order

+

User can add multiple products by clicking on "ADD MULTIPLE PRODUCTS" button on sale order.

+ +
+
+
+ +
+
+
+

Add Product Line on Sale Order

+

User can click on "Add a Line" option to add multiple product on sale order line.

+ +
+
+
+ +
+
+
+

Select Multiple Product on Sale Order

+

User can select multiple product to add in sale order line.

+ +
+
+
+ +
+
+
+

Confirm Selected Product

+ +
+
+
+ +
+
+
+

Added Multiple Products on Sale Order Line

+

User can see added multiple products on sale order line.

+ +
+
+
+ +
+
+
+

Add Multiple Products on Purchase Order

+

User can add multiple products by clicking on "ADD MULTIPLE PRODUCTS" button on purchase order.

+ +
+
+
+ +
+
+
+

Select Multiple Product on Purchase Order

+

User can select multiple product to add in purchase order line.

+ +
+
+
+ +
+
+
+

Added Multiple Products on Purchase Order Line

+

User can see added multiple products on purchase order line.

+ +
+
+
+ +
+
+
+

Add Multiple Products on Delivery Order

+

User can add multiple products by clicking on "ADD MULTIPLE PRODUCTS" button on delivery order.

+ +
+
+
+ +
+
+
+

Select Multiple Product on Delivery Order

+

User can select multiple product to add in delivery order line.

+ +
+
+
+ +
+
+
+

Added Multiple Products on Delivery Order Line

+

User can see added multiple products on delivery order line.

+ +
+
+
+ +
+
+
+

Add Multiple Products on an Invoice

+

User can add multiple products by clicking on "ADD MULTIPLE PRODUCTS" button on an invoice.

+ +
+
+
+ +
+
+
+

Select Multiple Product on an Invoice

+

User can select multiple product to add in invoice line.

+ +
+
+
+ +
+
+
+

Added Multiple Products on an Invoice Line

+

User can see added multiple products on an invoice line.

+ +
+
+
+ +
+
+
+
+

Apps May You Like

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

Most Demanded Apps

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

Free Support

+

You will get 90 Days free support incase any bugs or issue (Except data recovery).

+

+ At BrowseInfo we offer end to end solution for Odoo services. Which includes analysis & consultation on the workflows and integration part. Please note that You're not allowed to distribute this module after purchase! Incase of any question regarding this module feel free to email us on ticket@browseinfo.in or raise a ticket on support. +

+
+
+
+ +
+
+
+
+ + + +
+
+ +
+
diff --git a/odex25_sales/bi_multi_product_selection/static/description/related/bi_automated_sale_order.png b/odex25_sales/bi_multi_product_selection/static/description/related/bi_automated_sale_order.png new file mode 100644 index 000000000..43b47a72f Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/related/bi_automated_sale_order.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/related/bi_sale_auto_complete.png b/odex25_sales/bi_multi_product_selection/static/description/related/bi_sale_auto_complete.png new file mode 100644 index 000000000..7d16adbe8 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/related/bi_sale_auto_complete.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/related/bi_sale_loyalty.png b/odex25_sales/bi_multi_product_selection/static/description/related/bi_sale_loyalty.png new file mode 100644 index 000000000..6e6fac122 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/related/bi_sale_loyalty.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/related/bi_sale_tripple_approval.png b/odex25_sales/bi_multi_product_selection/static/description/related/bi_sale_tripple_approval.png new file mode 100644 index 000000000..b31f0928f Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/related/bi_sale_tripple_approval.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/related/bi_website_rma.png b/odex25_sales/bi_multi_product_selection/static/description/related/bi_website_rma.png new file mode 100644 index 000000000..c448e9899 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/related/bi_website_rma.png differ diff --git a/odex25_sales/bi_multi_product_selection/static/description/related/product_bundle_pack_advance.png b/odex25_sales/bi_multi_product_selection/static/description/related/product_bundle_pack_advance.png new file mode 100644 index 000000000..686d062e0 Binary files /dev/null and b/odex25_sales/bi_multi_product_selection/static/description/related/product_bundle_pack_advance.png differ diff --git a/odex25_sales/bi_multi_product_selection/views/account_move_view.xml b/odex25_sales/bi_multi_product_selection/views/account_move_view.xml new file mode 100644 index 000000000..660f976fa --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/views/account_move_view.xml @@ -0,0 +1,15 @@ + + + + account.move.form.inherit + account.move + + + +
+
+
+
+
+
\ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/views/purchase_order_view.xml b/odex25_sales/bi_multi_product_selection/views/purchase_order_view.xml new file mode 100644 index 000000000..3e79e85f7 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/views/purchase_order_view.xml @@ -0,0 +1,15 @@ + + + + purchase.order.form.inherit + purchase.order + + + +
+
+
+
+
+
\ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/views/sale_order_view.xml b/odex25_sales/bi_multi_product_selection/views/sale_order_view.xml new file mode 100644 index 000000000..84ca7342c --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/views/sale_order_view.xml @@ -0,0 +1,15 @@ + + + + sale.order.form.inherit + sale.order + + + +
+
+
+
+
+
\ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/views/stock_picking_view.xml b/odex25_sales/bi_multi_product_selection/views/stock_picking_view.xml new file mode 100644 index 000000000..33602e9e4 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/views/stock_picking_view.xml @@ -0,0 +1,15 @@ + + + + stock.picking.form.inherit + stock.picking + + + +
+
+
+
+
+
\ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/wizard/__init__.py b/odex25_sales/bi_multi_product_selection/wizard/__init__.py new file mode 100644 index 000000000..acf11c47b --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/wizard/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from . import sale_order_wizard +from . import purchase_order_wizard +from . import account_move_wizard +from . import stock_picking_wizard \ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/wizard/account_move_wizard.py b/odex25_sales/bi_multi_product_selection/wizard/account_move_wizard.py new file mode 100644 index 000000000..7ccf190c3 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/wizard/account_move_wizard.py @@ -0,0 +1,29 @@ +from odoo import _, api, fields, models, tools + + + +class AccountMoveWizard(models.TransientModel): + + _name = 'account.move.wizard' + _description = 'Account Move Wizard' + + product_ids = fields.Many2many('product.product',string="Select Products", required=True) + + def confirm_invoice_product(self): + active_id = self.env.context.get('active_ids', []) + get_active_id = self.env['account.move'].browse(active_id) + get_active_ids = self.env['account.move.line'].browse(active_id) + get_active_wizard_ids = self.env['account.move.wizard'].browse(active_id) + productobj = self.env['account.move.wizard'].search([('id', '=', self._context.get('active_id'))]) + order_line_vals = self.env['account.move'].search([]) + line_vals = self.product_ids + line_env = self.env['account.move.line'] + if get_active_id.state == 'draft': + for wizard in self: + for data in line_vals: + new_line = line_env.create({ + 'product_id': data.id, + 'move_id': get_active_id.id, + 'account_id': data.id + }) + return True \ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/wizard/account_move_wizard_view.xml b/odex25_sales/bi_multi_product_selection/wizard/account_move_wizard_view.xml new file mode 100644 index 000000000..1240e3f30 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/wizard/account_move_wizard_view.xml @@ -0,0 +1,26 @@ + + + + + account.move.wizard.form + account.move.wizard + +
+ +
+
+ +
+
+ + + Invoice Wizard + ir.actions.act_window + account.move.wizard + form + + new + +
\ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/wizard/purchase_order_wizard.py b/odex25_sales/bi_multi_product_selection/wizard/purchase_order_wizard.py new file mode 100644 index 000000000..7f38c703e --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/wizard/purchase_order_wizard.py @@ -0,0 +1,31 @@ +from odoo import _, api, fields, models, tools + + + +class PurchaseOrderWizard(models.TransientModel): + + _name = 'purchase.order.wizard' + _description = 'Purcahse Order Wizard' + + product_ids = fields.Many2many('product.product',string="Select Products", required=True) + + def confirm_purchase_product(self): + active_id = self.env.context.get('active_ids', []) + get_active_id = self.env['purchase.order'].browse(active_id) + get_active_ids = self.env['purchase.order.line'].browse(active_id) + get_active_wizard_ids = self.env['purchase.order.wizard'].browse(active_id) + productobj = self.env['purchase.order.wizard'].search([('id', '=', self._context.get('active_id'))]) + order_line_vals = self.env['purchase.order'].search([]) + line_vals = self.product_ids + + line_env = self.env['purchase.order.line'] + if get_active_id.state == 'draft': + for wizard in self: + for data in wizard.product_ids: + new_line = line_env.create({ + 'product_id': data.id, + 'order_id': get_active_id.id, + + }) + return True + \ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/wizard/purchase_order_wizard_view.xml b/odex25_sales/bi_multi_product_selection/wizard/purchase_order_wizard_view.xml new file mode 100644 index 000000000..698c74da9 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/wizard/purchase_order_wizard_view.xml @@ -0,0 +1,26 @@ + + + + + purchase.order.wizard.form + purchase.order.wizard + +
+ +
+
+ +
+
+ + + Purchase Order Wizard + ir.actions.act_window + purchase.order.wizard + form + + new + +
\ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/wizard/sale_order_wizard.py b/odex25_sales/bi_multi_product_selection/wizard/sale_order_wizard.py new file mode 100644 index 000000000..7af564e51 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/wizard/sale_order_wizard.py @@ -0,0 +1,37 @@ +from odoo import _, api, fields, models, tools + + + +class SelectProductWizard(models.TransientModel): + + _name = 'sale.order.wizard' + _description = 'Sale Order Wizard' + + product_ids = fields.Many2many('product.product',string="Select Products" ,required=True) + + + def confirm_sale_product(self): + active_id = self.env.context.get('active_ids', []) + get_active_id = self.env['sale.order'].browse(active_id) + get_active_ids = self.env['sale.order.line'].browse(active_id) + get_active_wizard_ids = self.env['sale.order.wizard'].browse(active_id) + productobj = self.env['sale.order.wizard'].search([('id', '=', self._context.get('active_id'))]) + order_line_vals = self.env['sale.order'].search([]) + line_vals = self.product_ids + + line_env = self.env['sale.order.line'] + if get_active_id.state == 'draft': + for wizard in self: + for data in wizard.product_ids: + new_line = line_env.create({ + 'product_id': data.id, + 'order_id': get_active_id.id, + + }) + + return True + + + + + diff --git a/odex25_sales/bi_multi_product_selection/wizard/sale_order_wizard_view.xml b/odex25_sales/bi_multi_product_selection/wizard/sale_order_wizard_view.xml new file mode 100644 index 000000000..922c56dbe --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/wizard/sale_order_wizard_view.xml @@ -0,0 +1,26 @@ + + + + + sale.order.wizard.form + sale.order.wizard + +
+ +
+
+ +
+
+ + + Sale Order Wizard + ir.actions.act_window + sale.order.wizard + form + + new + +
\ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/wizard/stock_picking_view.xml b/odex25_sales/bi_multi_product_selection/wizard/stock_picking_view.xml new file mode 100644 index 000000000..f625dfe80 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/wizard/stock_picking_view.xml @@ -0,0 +1,26 @@ + + + + + stock.picking.wizard.form + stock.picking.wizard + +
+ +
+
+ +
+
+ + + Transfer Wizard + ir.actions.act_window + stock.picking.wizard + form + + new + +
\ No newline at end of file diff --git a/odex25_sales/bi_multi_product_selection/wizard/stock_picking_wizard.py b/odex25_sales/bi_multi_product_selection/wizard/stock_picking_wizard.py new file mode 100644 index 000000000..ab4185970 --- /dev/null +++ b/odex25_sales/bi_multi_product_selection/wizard/stock_picking_wizard.py @@ -0,0 +1,40 @@ +from odoo import _, api, fields, models, tools + + + +class StockPickingWizard(models.TransientModel): + + _name = 'stock.picking.wizard' + _description = 'Stock Move Wizard' + + product_ids = fields.Many2many('product.product',string="Select Products", required=True) + + def confirm_stock_picking_product(self): + active_id = self.env.context.get('active_ids', []) + get_active_id = self.env['stock.picking'].browse(active_id) + get_active_ids = self.env['stock.move'].browse(active_id) + get_active_wizard_ids = self.env['stock.picking.wizard'].browse(active_id) + productobj = self.env['stock.picking.wizard'].search([('id', '=', self._context.get('active_id'))]) + order_line_vals = self.env['stock.picking'].search([]) + line_vals = self.product_ids + + line_env = self.env['stock.move'] + if get_active_id.state == 'draft': + for wizard in self: + for data in wizard.product_ids: + new_line = line_env.create({ + 'name':data.name, + 'product_id': data.id, + 'product_uom':data.uom_id.id, + 'location_id':get_active_id.location_id.id, + 'location_dest_id': get_active_id.location_dest_id.id, + 'picking_id': get_active_id.id, + 'picking_type_id':get_active_id.picking_type_id.id, + 'product_uom_qty':get_active_id.id, + 'company_id': get_active_id.company_id.id, + + + }) + return True + + \ No newline at end of file diff --git a/odex25_sales/crm_custom/__init__.py b/odex25_sales/crm_custom/__init__.py new file mode 100644 index 000000000..cde864bae --- /dev/null +++ b/odex25_sales/crm_custom/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models diff --git a/odex25_sales/crm_custom/__manifest__.py b/odex25_sales/crm_custom/__manifest__.py new file mode 100644 index 000000000..84b5039b5 --- /dev/null +++ b/odex25_sales/crm_custom/__manifest__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +{ + 'name': "CRM Custom", + 'version': "1.0", + 'category': "Odex25-Sales/Odex25-Sales", + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'summary': "New features for CRM", + 'description': """Contains new features for CRM such as new views""", + 'depends': ['crm', 'project_custom'], + 'data': [ + 'views/crm_lead_views.xml', + 'views/menu_views.xml', + 'views/product_service_views.xml', + 'views/res_partner_views.xml', + ], + 'installable': True, + 'application': False, +} diff --git a/odex25_sales/crm_custom/models/__init__.py b/odex25_sales/crm_custom/models/__init__.py new file mode 100644 index 000000000..a4ac4d9c4 --- /dev/null +++ b/odex25_sales/crm_custom/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import crm_lead + diff --git a/odex25_sales/crm_custom/models/crm_lead.py b/odex25_sales/crm_custom/models/crm_lead.py new file mode 100644 index 000000000..239c2d12e --- /dev/null +++ b/odex25_sales/crm_custom/models/crm_lead.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models + + +class Lead(models.Model): + _inherit = 'crm.lead' + + inquiry_date = fields.Date('Inquiry Date') + site_visit_date = fields.Date('Site Visit Date') + submit_date = fields.Date('Submit Date', default=fields.Date.context_today) + + bidbond = fields.Boolean('Bid Bond') + + project_country_id = fields.Many2one('res.country', 'Country') + project_state_id = fields.Many2one('res.country.state', string='Region') + city_id = fields.Many2one('res.country.city', 'City') + industry_id = fields.Many2one('res.partner.industry', 'Industry(Classification)') + sector_id = fields.Many2one('sector', 'Sector(Role)') + department_id = fields.Many2one('hr.department',string='Business Unit') + product_id = fields.Many2one('product.product',string='Services(Contract Type)', store=True) + + must_lead = fields.Boolean('Must Lead (RFI)') + + project_category_id = fields.Many2one('project.category', 'Project Category') + project_duration = fields.Integer('Project Duration (Months) As per (SOW)') + project_duration_internal = fields.Integer('Project Duration (Internal)') + total_site_area = fields.Float('Total Site Area (m2) (Excluding Building Footprint)') + main_building_prototype = fields.Float('Main Building Prototype Area (m2)') + main_building_site = fields.Float('Main Building Site Adaptation Area (m2)') + main_building_total = fields.Float('Main Building Total Area (m2)') + floor_area_ratio = fields.Float('Floor Area Ratio (FAR)') + site_works_area = fields.Float('Site Works Area (m2)') + ancillary_building_prototype = fields.Float('Ancillary Building Prototype Area (m2)') + ancillary_building_site = fields.Float('Ancillary Building Site Adaptation Area (m2)') + ancillary_building_total = fields.Float('Ancillary Buildings Total Area (m2)') + + + def action_crm_send(self): + ''' Opens a wizard to compose an email, with relevant mail template loaded by default ''' + self.ensure_one() + # template_id = self._find_mail_template() + lang = self.env.context.get('lang') + # template = self.env['mail.template'].browse(template_id) + # if template.lang: + # lang = template._render_lang(self.ids)[self.id] + ctx = { + 'default_model': 'crm.lead', + 'default_res_id': self.ids[0], + # 'default_use_template': bool(template_id), + # 'default_template_id': template_id, + 'default_composition_mode': 'comment', + 'mark_so_as_sent': True, + 'custom_layout': "mail.mail_notification_paynow", + "default_partner_ids": self.partner_id.ids, + 'force_email': True, + 'model_description': self.with_context(lang=lang).type, + } + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'mail.compose.message', + 'views': [(False, 'form')], + 'view_id': False, + 'target': 'new', + 'context': ctx, + } + + + def convert_rfp(self): + + self.type = 'opportunity' + self.must_lead = True diff --git a/odex25_sales/crm_custom/views/crm_lead_views.xml b/odex25_sales/crm_custom/views/crm_lead_views.xml new file mode 100644 index 000000000..7f35adcd9 --- /dev/null +++ b/odex25_sales/crm_custom/views/crm_lead_views.xml @@ -0,0 +1,193 @@ + + + + + + crm.lead.form + crm.lead + + + + + Reject + + + + + + + + + + + + diff --git a/odex25_sales/crm_expense/views/hr_expense_view.xml b/odex25_sales/crm_expense/views/hr_expense_view.xml new file mode 100644 index 000000000..55a35c3eb --- /dev/null +++ b/odex25_sales/crm_expense/views/hr_expense_view.xml @@ -0,0 +1,20 @@ + + + + + + hr.expense.form + hr.expense + + + + + + + + + + + + + diff --git a/odex25_sales/crm_lead_code/__init__.py b/odex25_sales/crm_lead_code/__init__.py new file mode 100644 index 000000000..313e253fb --- /dev/null +++ b/odex25_sales/crm_lead_code/__init__.py @@ -0,0 +1,6 @@ +############################################################################## +# For copyright and license notices, see __manifest__.py file in root directory +############################################################################## + +from . import models + diff --git a/odex25_sales/crm_lead_code/__manifest__.py b/odex25_sales/crm_lead_code/__manifest__.py new file mode 100644 index 000000000..f8d645711 --- /dev/null +++ b/odex25_sales/crm_lead_code/__manifest__.py @@ -0,0 +1,34 @@ +############################################################################## +# +# Copyright (c) +# 2015 Serv. Tec. Avanzados - Pedro M. Baeza (http://www.serviciosbaeza.com) +# 2015 AvanzOsc (http://www.avanzosc.es) +# +# 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 . +# +############################################################################## + +{ + "name": "Sequential Code for Leads / Opportunities", + "version": "14.0.1.0.0", + 'category':'Odex25-Sales/Odex25-Sales', + "author": "Tecnativa, AvanzOSC, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/crm", + "license": "AGPL-3", + "depends": ["crm_custom"], + "data": ["data/lead_sequence.xml", "views/crm_lead_view.xml"], + "installable": True, + "pre_init_hook": "create_code_equal_to_id", + "post_init_hook": "assign_old_sequences", +} diff --git a/odex25_sales/crm_lead_code/data/lead_sequence.xml b/odex25_sales/crm_lead_code/data/lead_sequence.xml new file mode 100644 index 000000000..224b649e0 --- /dev/null +++ b/odex25_sales/crm_lead_code/data/lead_sequence.xml @@ -0,0 +1,21 @@ + + + + + Lead Code + crm.lead.rfi + + 00 + RFI%(y)s- + + + + Lead Code + crm.lead.rfp + + 00 + RFP%(y)s- + + + + diff --git a/odex25_sales/crm_lead_code/models/__init__.py b/odex25_sales/crm_lead_code/models/__init__.py new file mode 100644 index 000000000..44216bedc --- /dev/null +++ b/odex25_sales/crm_lead_code/models/__init__.py @@ -0,0 +1,5 @@ +############################################################################# +# For copyright and license notices, see __manifest__.py file in root directory +############################################################################## + +from . import crm_lead diff --git a/odex25_sales/crm_lead_code/models/crm_lead.py b/odex25_sales/crm_lead_code/models/crm_lead.py new file mode 100644 index 000000000..4a8834740 --- /dev/null +++ b/odex25_sales/crm_lead_code/models/crm_lead.py @@ -0,0 +1,55 @@ +############################################################################## +# For copyright and license notices, see __manifest__.py file in root directory +############################################################################## + +from odoo import _, api, fields, models + + +class CrmLead(models.Model): + _inherit = "crm.lead" + + + code_rfp = fields.Char( + string="Number", required=True, default="/", readonly=True, copy=False, tracking=True + ) + + code_rfi = fields.Char( + string="Number", required=True, default="/", readonly=True, copy=False, tracking=True + ) + + _sql_constraints = [ + ("crm_lead_unique_code_rfp", "UNIQUE (code_rfp)", _("The code must be unique!")), + ("crm_lead_unique_code_rfi", "UNIQUE (code_rfi)", _("The code must be unique!")), + ] + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + if vals.get("code_rfi", "/") == "/" and vals.get('type') == 'lead': + vals['code_rfi'] = self.env['ir.sequence'].next_by_code('crm.lead.rfi') or _('/') + + if vals.get("code_rfp", "/") == "/" and vals.get('type') == 'opportunity': + vals['code_rfp'] = self.env['ir.sequence'].next_by_code('crm.lead.rfp') or _('/') + + return super().create(vals_list) + + + def convert_rfp(self): + super(CrmLead, self).convert_rfp() + self.code_rfp = self.env['ir.sequence'].next_by_code('crm.lead.rfp') or _('/') + + + + def name_get(self): + result = [] + for crm in self: + if self._context.get('default_type') == 'lead': + result.append((crm.id, crm.code_rfi)) + + if self._context.get('default_type') == 'opportunity': + result.append((crm.id, crm.code_rfp)) + + else: + result.append((crm.id, crm.code_rfp)) + + return result diff --git a/odex25_sales/crm_lead_code/static/description/icon.png b/odex25_sales/crm_lead_code/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/odex25_sales/crm_lead_code/static/description/icon.png differ diff --git a/odex25_sales/crm_lead_code/static/description/index.html b/odex25_sales/crm_lead_code/static/description/index.html new file mode 100644 index 000000000..b1b76d43f --- /dev/null +++ b/odex25_sales/crm_lead_code/static/description/index.html @@ -0,0 +1,426 @@ + + + + + + +Sequential Code for Leads / Opportunities + + + +
+

Sequential Code for Leads / Opportunities

+ + +

Beta License: AGPL-3 OCA/crm Translate me on Weblate Try me on Runbot

+

This module adds a sequential code for leads / opportunities.

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
  • AvanzOSC
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/crm project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/odex25_sales/crm_lead_code/views/crm_lead_view.xml b/odex25_sales/crm_lead_code/views/crm_lead_view.xml new file mode 100644 index 000000000..2890c728e --- /dev/null +++ b/odex25_sales/crm_lead_code/views/crm_lead_view.xml @@ -0,0 +1,72 @@ + + + crm.lead.form + crm.lead + + + + + + + + crm.lead.tree.lead + crm.lead + + + + + + + + + crm.lead.search.lead + crm.lead + + + + ['|', ('name', 'ilike', self), ('code_rfi', 'ilike', self)] + + + + + crm.lead.tree.opportunity + crm.lead + + + + + + + + + crm.lead.kanban.lead + crm.lead + + + + + + + + + crm.lead.search.opportunity + crm.lead + + + + ['|', ('name', 'ilike', self), ('code_rfp', 'ilike', self)] + + + + diff --git a/odex25_sales/cup_is_customer_is_vendor/README.md b/odex25_sales/cup_is_customer_is_vendor/README.md new file mode 100644 index 000000000..a9cb6b199 --- /dev/null +++ b/odex25_sales/cup_is_customer_is_vendor/README.md @@ -0,0 +1 @@ +"# cup_is_customer_is_vendor" diff --git a/odex25_sales/cup_is_customer_is_vendor/__init__.py b/odex25_sales/cup_is_customer_is_vendor/__init__.py new file mode 100644 index 000000000..5305644df --- /dev/null +++ b/odex25_sales/cup_is_customer_is_vendor/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models \ No newline at end of file diff --git a/odex25_sales/cup_is_customer_is_vendor/__manifest__.py b/odex25_sales/cup_is_customer_is_vendor/__manifest__.py new file mode 100644 index 000000000..7a4852205 --- /dev/null +++ b/odex25_sales/cup_is_customer_is_vendor/__manifest__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Is a Customer and Is a Vendor", + + 'summary': """ + Add Field Is a Customer And Is a Vendor""", + + 'description': """ + * Add Field Is a Customer And Is a Vendor checkbox Into The Partner Form For Identification.\n + * Easy To Use.\n + * User Can Manually Set / Unset Customer and Vendor Checkbox.\n + * Add Customer Filter In Sale Order.\n + * Add Vendor Filter In Purchase Order. + """, + + 'license': "LGPL-3", + 'images': ['static/description/cupdev2.png'], + 'author': "Yusup Nur Karimah", + 'website': "https://yusupnurkarimah.github.io/", + + # Categories can be used to filter modules in modules listing + # Check https://github.com/odoo/odoo/blob/12.0/odoo/addons/base/data/ir_module_category_data.xml + # for the full list + 'category': 'Odex25-Sales/Odex25-Sales', + 'version': '0.1', + + # any module necessary for this one to work correctly + 'depends': ['base','account','sale_management','purchase'], + + # always loaded + 'data': [ + # 'security/ir.model.access.csv', + 'views/views.xml', + ], +} \ No newline at end of file diff --git a/odex25_sales/cup_is_customer_is_vendor/models/__init__.py b/odex25_sales/cup_is_customer_is_vendor/models/__init__.py new file mode 100644 index 000000000..3066c1b24 --- /dev/null +++ b/odex25_sales/cup_is_customer_is_vendor/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from . import purchase +from . import res_partner +from . import sale \ No newline at end of file diff --git a/odex25_sales/cup_is_customer_is_vendor/models/purchase.py b/odex25_sales/cup_is_customer_is_vendor/models/purchase.py new file mode 100644 index 000000000..d4475666a --- /dev/null +++ b/odex25_sales/cup_is_customer_is_vendor/models/purchase.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api + +class PurchaseOrder(models.Model): + _inherit = 'purchase.order' + + READONLY_STATES = { + 'purchase': [('readonly', True)], + 'done': [('readonly', True)], + 'cancel': [('readonly', True)], + } + + partner_id = fields.Many2one( + 'res.partner', string='Vendor', required=True, + states=READONLY_STATES, change_default=True, + tracking=True, domain="['|',('supplier_rank','>', 0),('is_supplier','=',True)]", help="You can find a vendor by its Name, TIN, Email or Internal Reference.") + \ No newline at end of file diff --git a/odex25_sales/cup_is_customer_is_vendor/models/res_partner.py b/odex25_sales/cup_is_customer_is_vendor/models/res_partner.py new file mode 100644 index 000000000..76b566d84 --- /dev/null +++ b/odex25_sales/cup_is_customer_is_vendor/models/res_partner.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api + +class ResPartner(models.Model): + _inherit = 'res.partner' + + is_customer = fields.Boolean(string='Is a Customer', + help="Check this box if this contact is a customer. It can be selected in sales orders.") + is_supplier = fields.Boolean(string='Is a Vendor', + help="Check this box if this contact is a vendor. It can be selected in purchase orders.") + \ No newline at end of file diff --git a/odex25_sales/cup_is_customer_is_vendor/models/sale.py b/odex25_sales/cup_is_customer_is_vendor/models/sale.py new file mode 100644 index 000000000..cd77b960b --- /dev/null +++ b/odex25_sales/cup_is_customer_is_vendor/models/sale.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + partner_id = fields.Many2one( + 'res.partner', string='Customer', readonly=True, + states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, + required=True, change_default=True, index=True, tracking=1, + domain="['|',('customer_rank','>', 0),('is_customer','=',True)]",) + \ No newline at end of file diff --git a/odex25_sales/cup_is_customer_is_vendor/security/ir.model.access.csv b/odex25_sales/cup_is_customer_is_vendor/security/ir.model.access.csv new file mode 100644 index 000000000..272542302 --- /dev/null +++ b/odex25_sales/cup_is_customer_is_vendor/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_cup_is_customer_is_vendor_cup_is_customer_is_vendor,cup_is_customer_is_vendor.cup_is_customer_is_vendor,model_cup_is_customer_is_vendor_cup_is_customer_is_vendor,,1,0,0,0 \ No newline at end of file diff --git a/odex25_sales/cup_is_customer_is_vendor/static/description/cupdev.png b/odex25_sales/cup_is_customer_is_vendor/static/description/cupdev.png new file mode 100644 index 000000000..305131e33 Binary files /dev/null and b/odex25_sales/cup_is_customer_is_vendor/static/description/cupdev.png differ diff --git a/odex25_sales/cup_is_customer_is_vendor/static/description/cupdev2.png b/odex25_sales/cup_is_customer_is_vendor/static/description/cupdev2.png new file mode 100644 index 000000000..4ab5a1d08 Binary files /dev/null and b/odex25_sales/cup_is_customer_is_vendor/static/description/cupdev2.png differ diff --git a/odex25_sales/cup_is_customer_is_vendor/static/description/icon.png b/odex25_sales/cup_is_customer_is_vendor/static/description/icon.png new file mode 100644 index 000000000..146341ef0 Binary files /dev/null and b/odex25_sales/cup_is_customer_is_vendor/static/description/icon.png differ diff --git a/odex25_sales/cup_is_customer_is_vendor/views/views.xml b/odex25_sales/cup_is_customer_is_vendor/views/views.xml new file mode 100644 index 000000000..685d60c81 --- /dev/null +++ b/odex25_sales/cup_is_customer_is_vendor/views/views.xml @@ -0,0 +1,63 @@ + + + + + + view_partner_form_inherit + res.partner + + + + + + + + + + + + + + Customers + ir.actions.act_window + res.partner + kanban,tree,form + {'search_default_customer': 1,'res_partner_search_mode': 'customer', 'default_is_company': True, 'default_customer_rank': 1, 'default_is_customer': True} + +

+ Create a new customer in your address book +

+ Odoo helps you easily track all activities related to a customer. +

+
+
+ + Vendors + ir.actions.act_window + res.partner + kanban,tree,form + {'search_default_supplier': 1,'res_partner_search_mode': 'supplier', 'default_is_company': True, 'default_supplier_rank': 1, 'default_is_supplier': True} + +

+ Create a new supplier in your address book +

+ Odoo helps you easily track all activities related to a supplier. +

+
+
+ + + + res.partner.search.inherit + res.partner + + + + + + + + + +
+
\ No newline at end of file diff --git a/odex25_sales/customer_credit_limit/__init__.py b/odex25_sales/customer_credit_limit/__init__.py new file mode 100644 index 000000000..9a7e03ede --- /dev/null +++ b/odex25_sales/customer_credit_limit/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/odex25_sales/customer_credit_limit/__manifest__.py b/odex25_sales/customer_credit_limit/__manifest__.py new file mode 100644 index 000000000..4221a07f2 --- /dev/null +++ b/odex25_sales/customer_credit_limit/__manifest__.py @@ -0,0 +1,22 @@ + +{ + "name": "Customer Credit Limit", + "summary": """Customer Credit Limit""", + "version": '14.0', + "category":'Odex25-Sales/Odex25-Sales', + 'author': 'Expert Co. Ltd.', + 'website': 'http://exp-sa.com', + "depends": ['odex25_global_discount', 'sale_partner_type'], + "data": [ + 'security/security.xml', + 'views/res_partner.xml', + 'views/res_config.xml', + 'views/sale_order.xml', + ], + + "sequence": 3, + "application": False, + "installable": True, + "auto_install": False, + +} \ No newline at end of file diff --git a/odex25_sales/customer_credit_limit/i18n/ar_001.po b/odex25_sales/customer_credit_limit/i18n/ar_001.po new file mode 100644 index 000000000..e15d02c22 --- /dev/null +++ b/odex25_sales/customer_credit_limit/i18n/ar_001.po @@ -0,0 +1,226 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * customer_credit_limit +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-06-25 11:36+0000\n" +"PO-Revision-Date: 2023-06-25 11:36+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: customer_credit_limit +#: code:addons/customer_credit_limit/models/sale_order.py:0 +#, python-format +msgid " You Need To Pay Old Invoices " +msgstr "تحتاج الي Ø¯ÙØ¹ الÙواتير القديمة" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_partner__allow +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_users__allow +#: model:ir.model.fields,field_description:customer_credit_limit.field_sale_order__allow +msgid "Allow Sale" +msgstr "السماح بالبيع" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_partner__block +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_users__block +msgid "Block From Sale" +msgstr "منع من البيع" + +#. module: customer_credit_limit +#: model:ir.model,name:customer_credit_limit.model_res_config_settings +msgid "Config Settings" +msgstr "ضبط الاعدادات" + +#. module: customer_credit_limit +#: model:ir.model,name:customer_credit_limit.model_res_partner +msgid "Contact" +msgstr "جهة الاتصال" + +#. module: customer_credit_limit +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_view_partner_form +msgid "Credit Limit" +msgstr "حد الإئتمان" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_partner__credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_users__credit_limit +msgid "Customer Credit Limit" +msgstr "الحد الإئتماني للعملاء" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_partner__due_days +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_users__due_days +msgid "Days To Pay" +msgstr "عدد الأيام المسموح بها Ù„Ù„Ø¯ÙØ¹" + +#. module: customer_credit_limit +#: model:ir.module.category,name:customer_credit_limit.module_category_discounts +msgid "Discount" +msgstr "الخصم" + +#. module: customer_credit_limit +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "Discounts" +msgstr "الخصومات" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__display_name +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_partner__display_name +#: model:ir.model.fields,field_description:customer_credit_limit.field_sale_order__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: customer_credit_limit +#: model:res.groups,name:customer_credit_limit.discount_firt_level +msgid "First Level" +msgstr "المستوي الاول" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__amount_limit_a +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "First Level Amount Limit" +msgstr "حد مبلغ المستوي الاول" + +#. module: customer_credit_limit +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "First Level Percent Limit" +msgstr "حد نسبة المستوي الاول" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__percent_limit_a +msgid "First Level Percent Limit " +msgstr "حد نسبة المستوي الاول" + +#. module: customer_credit_limit +#: model:res.groups,name:customer_credit_limit.discount_fourth_level +msgid "Fourth Level" +msgstr "المستوي الرابع" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__amount_limit_d +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "Fourth Level Amount Limit" +msgstr "حد مبلغ المستوي الرابع" + +#. module: customer_credit_limit +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "Fourth Level Percent Limit" +msgstr "حد نسبة المستوي الرابع" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__percent_limit_d +msgid "Fourth Level Percent Limit " +msgstr "حد نسبة المستوي الرابع" + +#. module: customer_credit_limit +#: model:ir.module.category,description:customer_credit_limit.module_category_discounts +msgid "Helps you handle your discounts." +msgstr "يساعدك على التعامل مع الخصومات الخاصة بك" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__id +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_partner__id +#: model:ir.model.fields,field_description:customer_credit_limit.field_sale_order__id +msgid "ID" +msgstr "Ø§Ù„Ù…ÙØ¹Ø±Ù" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings____last_update +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_partner____last_update +#: model:ir.model.fields,field_description:customer_credit_limit.field_sale_order____last_update +msgid "Last Modified on" +msgstr "آخر تعديل ÙÙŠ" + +#. module: customer_credit_limit +#: model:ir.model,name:customer_credit_limit.model_sale_order +msgid "Sales Order" +msgstr "أمر البيع" + +#. module: customer_credit_limit +#: model:res.groups,name:customer_credit_limit.discount_second_level +msgid "Second Level" +msgstr "المستوي الثاني" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__amount_limit_b +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "Second Level Amount Limit" +msgstr "حد مبلغ المستوي الثاني" + +#. module: customer_credit_limit +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "Second Level Percent Limit" +msgstr "حد نسبة المستوي الثاني" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__percent_limit_b +msgid "Second Level Percent Limit " +msgstr "حد نسبة المستوي الثاني" + +#. module: customer_credit_limit +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "Set discounts for levels to use in sale." +msgstr "تعيين الخصومات للمستويات لاستخدامها ÙÙŠ البيع" + +#. module: customer_credit_limit +#: model:res.groups,name:customer_credit_limit.discount_third_level +msgid "Third Level" +msgstr "المستوي الثالث" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__amount_limit_c +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "Third Level Amount Limit" +msgstr "حد مبلغ المستوي الثالث" + +#. module: customer_credit_limit +#: model_terms:ir.ui.view,arch_db:customer_credit_limit.inherit_config_settings_view_form +msgid "Third Level Percent Limit" +msgstr "حد نسبة المستوي الثالث" + +#. module: customer_credit_limit +#: model:ir.model.fields,field_description:customer_credit_limit.field_res_config_settings__percent_limit_c +msgid "Third Level Percent Limit " +msgstr "حد نسبة المستوي الثالث" + +#. module: customer_credit_limit +#: code:addons/customer_credit_limit/models/sale_order.py:0 +#, python-format +msgid "This Partner Has limit Credit Which Is %s ,%s" +msgstr "العميل لدية حد ائتمان وهو %s ,%s" + +#. module: customer_credit_limit +#: code:addons/customer_credit_limit/models/sale_order.py:0 +#, python-format +msgid "" +"This Partner Is Blocked From Doing Sale Due To Delay In Payments,To Unlock " +"It Stop Block From Sale Order Or Customer Profile" +msgstr "هذا العميل ممنوع من القيام بالبيع بسبب التأخير ÙÙŠ المدÙوعات ØŒ لإلغاء Ù‚Ùله وإيقاÙÙ‡ من أمر البيع أو المل٠الشخصي للعميل" + +#. module: customer_credit_limit +#: code:addons/customer_credit_limit/models/sale_order.py:0 +#, python-format +msgid "You Can Create Orders With Total %d" +msgstr "يمكنك انشاء امر بيع بالاجمالي %d" + +#. module: customer_credit_limit +#: code:addons/customer_credit_limit/models/sale_order.py:0 +#: code:addons/customer_credit_limit/models/sale_order.py:0 +#, python-format +msgid "You cannot exceed amount limit which is %s ." +msgstr "لا يمكنك تجاوز حد المبلغ الذي هو %s ." + +#. module: customer_credit_limit +#: code:addons/customer_credit_limit/models/sale_order.py:0 +#, python-format +msgid "You cannot exceed percent limit which is %s." +msgstr "لا يمكنك تجاوز حد النسبة المئوية وهو %s." + diff --git a/odex25_sales/customer_credit_limit/models/__init__.py b/odex25_sales/customer_credit_limit/models/__init__.py new file mode 100644 index 000000000..059049c5b --- /dev/null +++ b/odex25_sales/customer_credit_limit/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from . import res_partner +from . import sale_order +from . import res_config diff --git a/odex25_sales/customer_credit_limit/models/res_config.py b/odex25_sales/customer_credit_limit/models/res_config.py new file mode 100644 index 000000000..30e674224 --- /dev/null +++ b/odex25_sales/customer_credit_limit/models/res_config.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + percent_limit_a = fields.Float(string='First Level Percent Limit ',) + amount_limit_a = fields.Float(string='First Level Amount Limit',) + percent_limit_b = fields.Float(string='Second Level Percent Limit ',) + amount_limit_b = fields.Float(string='Second Level Amount Limit',) + percent_limit_c = fields.Float(string='Third Level Percent Limit ',) + amount_limit_c = fields.Float(string='Third Level Amount Limit',) + percent_limit_d = fields.Float(string='Fourth Level Percent Limit ',) + amount_limit_d = fields.Float(string='Fourth Level Amount Limit',) + + def get_values(self): + res = super(ResConfigSettings, self).get_values() + res.update( + percent_limit_a=float(self.env['ir.config_parameter']. + get_param('percent_limit_a')), + amount_limit_a=float(self.env['ir.config_parameter']. + get_param('amount_limit_a')), + + percent_limit_b=float(self.env['ir.config_parameter']. + get_param('percent_limit_b')), + amount_limit_b=float(self.env['ir.config_parameter']. + get_param('amount_limit_b')), + + percent_limit_c=float(self.env['ir.config_parameter']. + get_param('percent_limit_c')), + amount_limit_c=float(self.env['ir.config_parameter']. + get_param('amount_limit_c')), + + percent_limit_d=float(self.env['ir.config_parameter']. + get_param('percent_limit_d')), + amount_limit_d=float(self.env['ir.config_parameter']. + get_param('amount_limit_d')), + + ) + return res + + def set_values(self): + super(ResConfigSettings, self).set_values() + # self.env['ir.config_parameter'].set_param('ks_enable_discount', self.ks_enable_discount) + # if self.ks_enable_discount: + self.env['ir.config_parameter'].set_param('percent_limit_a', self.percent_limit_a) + self.env['ir.config_parameter'].set_param('amount_limit_a', self.amount_limit_a) + self.env['ir.config_parameter'].set_param('percent_limit_b', self.percent_limit_b) + self.env['ir.config_parameter'].set_param('amount_limit_b', self.amount_limit_b) + self.env['ir.config_parameter'].set_param('percent_limit_c', self.percent_limit_c) + self.env['ir.config_parameter'].set_param('amount_limit_c', self.amount_limit_c) + self.env['ir.config_parameter'].set_param('percent_limit_d', self.percent_limit_d) + self.env['ir.config_parameter'].set_param('amount_limit_d', self.amount_limit_d) diff --git a/odex25_sales/customer_credit_limit/models/res_partner.py b/odex25_sales/customer_credit_limit/models/res_partner.py new file mode 100644 index 000000000..6cb35084e --- /dev/null +++ b/odex25_sales/customer_credit_limit/models/res_partner.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models, _ +from datetime import datetime, timedelta + + +class ResPartner(models.Model): + _inherit = "res.partner" + + + credit_limit = fields.Float(string='Customer Credit Limit', tracking=True) + + + block = fields.Boolean(string='Block From Sale', compute='_compute_sale_block') + + allow = fields.Boolean(string='Allow Sale',groups='sales_team.group_sale_manager', tracking=True) + + + due_days = fields.Float(string='Days To Pay', default=30.0, tracking=True) + + @api.depends('due_days','invoice_ids') + def _compute_sale_block(self): + '''this functin search for partner related open inovices with due date, + to determine whether to block customer from making sale or not''' + + for rec in self: + rec.block = False + + if rec.due_days > 0 : + today = datetime.now().date() + date = today - timedelta(days=rec.due_days) + invoices = rec.invoice_ids.filtered(lambda r: r.invoice_date_due and r.invoice_date_due <= date and r.move_type =='out_invoice' and r.state == 'posted') + + if invoices: + rec.block = True + + diff --git a/odex25_sales/customer_credit_limit/models/sale_order.py b/odex25_sales/customer_credit_limit/models/sale_order.py new file mode 100644 index 000000000..0f99b6daa --- /dev/null +++ b/odex25_sales/customer_credit_limit/models/sale_order.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + allow = fields.Boolean(string='Allow Sale') + credit_limit = fields.Float(string='Credit Limit', related='partner_id.credit_limit') + customer_balance = fields.Float(string='Customer Balance', readonly=True) + + def write(self, vals): + if 'partner_id' in vals: + partner = self.env['res.partner'].browse(vals['partner_id']) + self.customer_balance = partner.credit - partner.debit + return super(SaleOrder, self).write(vals) + + @api.onchange('partner_id') + def get_allow_sale(self): + self.allow = self.partner_id.allow + + def _action_confirm(self): + for rec in self: + if not rec.allow: + if rec.partner_id.block and not rec.partner_id.allow and rec.partner_type == 'postpaid': + raise ValidationError( + _("This Partner Is Blocked From Doing Sale Due To Delay In Payments,To Unlock It Stop Block From Sale Order Or Customer Profile")) + if rec.partner_id.credit_limit > 0 and rec.partner_type == 'postpaid': + last_total = rec.partner_id.credit + rec.amount_total + limit = rec.partner_id.credit_limit - rec.partner_id.credit + msg = (_("You Can Create Orders With Total %d")) % limit if limit > 0 else ( + _(" You Need To Pay Old Invoices ")) + if rec.partner_id.credit >= rec.partner_id.credit_limit or last_total > rec.partner_id.credit_limit: + raise ValidationError( + _("This Partner Has limit Credit Which Is %s ,%s") % (rec.partner_id.credit_limit, msg)) + return super(SaleOrder, self)._action_confirm() + + @api.constrains('discount_amount') + def check_discount_value(self): + percent_limit = 0.0 + amount_limit = 0.0 + if self.amount_untaxed: + percent = (self.discount_amount / self.amount_untaxed) * 100 + + if self.env.user.has_group('customer_credit_limit.discount_firt_level'): + percent_limit = float(self.env['ir.config_parameter'].sudo().get_param('percent_limit_a')) + amount_limit = float(self.env['ir.config_parameter'].sudo().get_param('amount_limit_a')) + + elif self.env.user.has_group('customer_credit_limit.discount_second_level'): + percent_limit = float(self.env['ir.config_parameter'].sudo().get_param('percent_limit_b')) + amount_limit = float(self.env['ir.config_parameter'].sudo().get_param('amount_limit_b')) + + elif self.env.user.has_group('customer_credit_limit.discount_third_level'): + percent_limit = float(self.env['ir.config_parameter'].sudo().get_param('percent_limit_c')) + amount_limit = float(self.env['ir.config_parameter'].sudo().get_param('amount_limit_c')) + + elif self.env.user.has_group('customer_credit_limit.discount_fourth_level'): + percent_limit = float(self.env['ir.config_parameter'].sudo().get_param('percent_limit_d')) + amount_limit = float(self.env['ir.config_parameter'].sudo().get_param('amount_limit_d')) + + if self.discount_method == 'per' and self.discount_amount > percent_limit: + raise ValidationError(_('You cannot exceed percent limit which is %s.') % percent_limit) + + if self.discount_method == 'fix': + if self.discount_amount > amount_limit: + raise ValidationError(_('You cannot exceed amount limit which is %s .') % amount_limit) + + elif percent > percent_limit: + raise ValidationError(_('You cannot exceed amount limit which is %s .') % percent_limit) diff --git a/odex25_sales/customer_credit_limit/security/security.xml b/odex25_sales/customer_credit_limit/security/security.xml new file mode 100644 index 000000000..40bf15a7c --- /dev/null +++ b/odex25_sales/customer_credit_limit/security/security.xml @@ -0,0 +1,32 @@ + + + + + + Discount + Helps you handle your discounts. + + + + First Level + + + + + Third Level + + + + + + Second Level + + + + Fourth Level + + + + + + diff --git a/odex25_sales/customer_credit_limit/static/description/icon.png b/odex25_sales/customer_credit_limit/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_sales/customer_credit_limit/static/description/icon.png differ diff --git a/odex25_sales/customer_credit_limit/static/fonts/ae_AlMohanad.ttf b/odex25_sales/customer_credit_limit/static/fonts/ae_AlMohanad.ttf new file mode 100644 index 000000000..bdd7360e1 Binary files /dev/null and b/odex25_sales/customer_credit_limit/static/fonts/ae_AlMohanad.ttf differ diff --git a/odex25_sales/customer_credit_limit/views/res_config.xml b/odex25_sales/customer_credit_limit/views/res_config.xml new file mode 100644 index 000000000..b1f38680d --- /dev/null +++ b/odex25_sales/customer_credit_limit/views/res_config.xml @@ -0,0 +1,69 @@ + + + + inherit.res.config.settings + res.config.settings + + + + + +

Discounts

+
+
+
+
+ +
+ Set discounts for levels to use in sale. +
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
+ + + + + + + \ No newline at end of file diff --git a/odex25_sales/customer_credit_limit/views/res_partner.xml b/odex25_sales/customer_credit_limit/views/res_partner.xml new file mode 100644 index 000000000..2ec05ead2 --- /dev/null +++ b/odex25_sales/customer_credit_limit/views/res_partner.xml @@ -0,0 +1,31 @@ + + + + + res.partner + res.partner + + + + + + + + + + + + + + + sale.order.form + sale.order + + + + + + + + + diff --git a/odex25_sales/customer_credit_limit/views/sale_order.xml b/odex25_sales/customer_credit_limit/views/sale_order.xml new file mode 100644 index 000000000..85e7fc52f --- /dev/null +++ b/odex25_sales/customer_credit_limit/views/sale_order.xml @@ -0,0 +1,14 @@ + + + + inherit.view.sale.order.form + sale.order + + + + + + + + + \ No newline at end of file diff --git a/odex25_sales/dev_membership/LICENSE b/odex25_sales/dev_membership/LICENSE new file mode 100644 index 000000000..7a5c68e71 --- /dev/null +++ b/odex25_sales/dev_membership/LICENSE @@ -0,0 +1,27 @@ +Odoo Proprietary License v1.0 + +This software and associated files (the "Software") may only be used (executed, +modified, executed after modifications) if you have purchased a valid license +from the authors, typically via Odoo Apps, or if you have received a written +agreement from the authors of the Software (see the COPYRIGHT file). + +You may develop Odoo modules that use the Software as a library (typically +by depending on it, importing it and using its resources), but without copying +any source code or material from the Software. You may distribute those +modules under the license of your choice, provided that this license is +compatible with the terms of the Odoo Proprietary License (For example: +LGPL, MIT, or proprietary licenses similar to this one). + +It is forbidden to publish, distribute, sublicense, or sell copies of the Software +or modified copies of the Software. + +The above copyright notice and this permission notice must be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/odex25_sales/dev_membership/__init__.py b/odex25_sales/dev_membership/__init__.py new file mode 100644 index 000000000..71daf1dc0 --- /dev/null +++ b/odex25_sales/dev_membership/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (). +# +# For Module Support : devintelle@gmail.com or Skype : devintelle +# +############################################################################## + +from . import models +from . import report +from . import wizard + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex25_sales/dev_membership/__manifest__.py b/odex25_sales/dev_membership/__manifest__.py new file mode 100644 index 000000000..6ba49b6bf --- /dev/null +++ b/odex25_sales/dev_membership/__manifest__.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (). +# +# For Module Support : devintelle@gmail.com or Skype : devintelle +# +############################################################################## + +{ + 'name': 'Membership Management, Membership subscription Plans', + 'version': '15.0.1.0', + 'sequence': 1, + 'category': 'Odex25-Sales/Odex25-Sales', + 'description': + """ + This Module add below functionality into odoo + + 1.Membership Management, Membership subscription Plans\n + + odoo application you can easily manage Membership. Define various membership products, create members and create their membership. + +Manage membership inside the odoo + Create and manage members + Create Membership Product, you can decide the period of membership here it may be N number of Days, Months or Years + Create Membership for the member, select membership product there and duration of membership will be automatically loaded based on membership product + Create Invoice for the membership + You can activate membership only when invoice is paid + Membership will be automatically expire on its expiry date + Once membership is expired you can Renew membership from there + Separate menus provided for Active and Expire membership + Send membership into the email to the Member + Print membership as PDF Report + Configure membership expiry before days so it will send notification email to the member before N number of days of expiry date of membership + Role of Users: + + Membership > User + Membership > Manager + + Membership Plans +Member Onboarding +Subscription Management +Renewal Notifications +Member Database +Access Control +Billing and Invoicing +Automated Renewals +Membership Tiers +Member Benefits +Membership Analytics +Member Engagement +Attendance Tracking +Event Management +Payment Gateway Integration +Custom Membership Fields +Membership Expiry Alerts +Reporting and Analytics +Membership Fees +Membership Cancellation Process + +odoo app manage Membership subscription plans, odoo membership memeber, odoo member list, subscription renew, membership renew, member engagement, member expiry, membership recuring plans, membership billing, subscription expiry, subscription tracking, subscription methods and fees, membership list + + """, + 'summary': 'odoo app manage Membership subscription plans, odoo membership memeber, odoo member list, subscription renew, membership renew, member engagement, member expiry, membership recuring plans, membership billing, subscription expiry, subscription tracking, subscription methods and fees, membership list', + 'depends': ['sale_management'], + 'data': [ + 'security/security.xml', + 'security/ir.model.access.csv', + 'data/sequence.xml', + 'views/main_menu.xml', + 'wizard/renew_membership.xml', + 'views/partner_extended.xml', + 'views/dev_membership.xml', + 'views/product_template.xml', + 'views/res_config_settings.xml', + 'report/print_membership_template.xml', + 'report/print_membership_menu.xml', + 'data/mail_template.xml', + ], + 'demo': [], + 'test': [], + 'css': [], + 'qweb': [], + 'js': [], + 'images': ['images/main_screenshot.png'], + 'installable': True, + 'application': True, + 'auto_install': False, + + # author and support Details =============# + 'author': 'DevIntelle Consulting Service Pvt.Ltd', + 'website': 'http://www.devintellecs.com', + 'maintainer': 'DevIntelle Consulting Service Pvt.Ltd', + 'support': 'devintelle@gmail.com', + 'price':39.0, + 'currency':'EUR', + #'live_test_url':'https://youtu.be/A5kEBboAh_k', + 'license':'LGPL-3', +} + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex25_sales/dev_membership/contributors.txt b/odex25_sales/dev_membership/contributors.txt new file mode 100644 index 000000000..ad7071c89 --- /dev/null +++ b/odex25_sales/dev_membership/contributors.txt @@ -0,0 +1,7 @@ + +DevintelleCS Odoo Expert Team + +Get in Touch for other odoo Devlopment & Support: +Skype: devintelle +What's app : +91 8780543446 +Mail: devintelle@gmail.com \ No newline at end of file diff --git a/odex25_sales/dev_membership/data/mail_template.xml b/odex25_sales/dev_membership/data/mail_template.xml new file mode 100644 index 000000000..4da794406 --- /dev/null +++ b/odex25_sales/dev_membership/data/mail_template.xml @@ -0,0 +1,53 @@ + + + + membership.email.template + Membership Detail + ${(object.company_id and object.company_id.email or '') | safe} + ${object.partner_id.id} + + + ${(object.name)}_Membership + + +
+

Hello ${object.partner_id.name},

+

Your ${object.product_id.name} membership of amount ${object.membership_fees} have activated on ${object.from_date} - ${object.to_date} .

+
+
+
+

Regards,

+

${object.company_id.name}

+
+
+
+ + + Membership Expire Reminder + ${(object.company_id.email or '') | safe} + ${(object.partner_id.email or '') | safe} + Membership Expire Reminder + + + Hello ${object.partner_id.name}.

+

Hope you doing well!

+

It's gentle reminder that your membership is about to expire on ${object.datetime_convert()}.

+ ]]>
+
+ + + Membership Expired Mail + ${(object.company_id.email or '') | safe} + ${(object.partner_id.email or '') | safe} + Your membership ${(object.name)} Expired + + + Hello ${object.partner_id.name},

+

Hope you doing well!

+

Your membership ${(object.name)} was expired on ${object.datetime_convert()} date.

+ ]]>
+
+ +
diff --git a/odex25_sales/dev_membership/data/sequence.xml b/odex25_sales/dev_membership/data/sequence.xml new file mode 100644 index 000000000..46c7681ab --- /dev/null +++ b/odex25_sales/dev_membership/data/sequence.xml @@ -0,0 +1,41 @@ + + + + + + seq.dev.membership + seq.dev.membership + MEM/%(year)s/ + 4 + + + + + Membership Reminder + + 1 + days + -1 + + + code + model.membership_reminder_email_cron() + + + + + Auto Expire Membership + + 1 + days + -1 + + + code + model.membership_auto_expire() + + diff --git a/odex25_sales/dev_membership/images/main_screenshot.png b/odex25_sales/dev_membership/images/main_screenshot.png new file mode 100644 index 000000000..8de6cdb1a Binary files /dev/null and b/odex25_sales/dev_membership/images/main_screenshot.png differ diff --git a/odex25_sales/dev_membership/models/__init__.py b/odex25_sales/dev_membership/models/__init__.py new file mode 100644 index 000000000..85ff801a2 --- /dev/null +++ b/odex25_sales/dev_membership/models/__init__.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (). +# +# For Module Support : devintelle@gmail.com or Skype : devintelle +# +############################################################################## + +from . import res_partner +from . import product_template +from . import dev_membership +from . import res_config_settings + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex25_sales/dev_membership/models/dev_membership.py b/odex25_sales/dev_membership/models/dev_membership.py new file mode 100644 index 000000000..2f61560d1 --- /dev/null +++ b/odex25_sales/dev_membership/models/dev_membership.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (). +# +# For Module Support : devintelle@gmail.com or Skype : devintelle +# +############################################################################## + +from odoo import fields, models, api, _ +from datetime import datetime +from dateutil.relativedelta import relativedelta +from odoo.exceptions import UserError, ValidationError + + +class DevMembership(models.Model): + _name = 'dev.membership' + _inherit = ['mail.thread', 'mail.activity.mixin'] + _description = 'Dev Membership' + _order = 'name desc' + + + 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())) + to_date = fields.Date(string="Membership To Date", tracking=3) + partner_id = fields.Many2one('res.partner', string="Partner", domain="[('is_member', '=', True)]", tracking=2, required=1) + product_id = fields.Many2one('product.product', string="Membership Product", domain="[('is_membership', '=', True)]", tracking=2, required=1) + membership_fees = fields.Float(string="Membership Fees", related="product_id.list_price", readonly=1) + company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.company, required=1, tracking=3) + duration = fields.Integer(string="Duration", related="product_id.duration") + description = fields.Text(string="Description", related="product_id.description", readonly=False) + interval = fields.Selection(string="Interval", related="product_id.interval") + + state = fields.Selection(string="State", selection=([('draft', 'Draft'), + ('confirm', 'Confirm'), + ('active', 'Active'), + ('expire', 'Expire'), + ('cancel', 'Cancel')]), default='draft', tracking=1) + + membership_id = fields.Many2one('dev.membership', string='Renew Membership') + invoice_id = fields.Many2one('account.move', string='Invoice') + user_id = fields.Many2one('res.users', string='Resposible', default=lambda self:self.env.user) + + + @api.constrains('from_date') + def _check_from_date(self): + for rec in self: + if not rec.from_date >= datetime.now().date(): + raise ValidationError("Membership date should be greater than or equal to today's date!!") + + @api.constrains('partner_id', 'from_date') + def _check_if_membership_exists(self): + membership_obj = self.env['dev.membership'].search([('partner_id.id', '=', self.partner_id.id), ('state', 'in', ['draft', 'active', 'confirm']), ('id', '!=', self.id)]) + if membership_obj: + for rec in self: + for membership in membership_obj: + if rec.from_date < membership.to_date: + raise ValidationError( + _("You already have a membership from '%s' to '%s' !!!!") % (membership.from_date, membership.to_date)) + + + @api.onchange('from_date', 'product_id', 'duration','interval') + def onchange_from_date(self): + if self.from_date and self.product_id: + if self.interval == 'year': + self.to_date = self.from_date + relativedelta(years=+self.duration) - relativedelta(days=1) + elif self.interval == 'month': + self.to_date = self.from_date + relativedelta(months=+self.duration) - relativedelta(days=1) + elif self.interval == 'days': + self.to_date = self.from_date + relativedelta(days=+self.duration) + + def action_confirm_membership(self): + self.state = 'confirm' + + def action_active_membership(self): + if not self.invoice_id: + raise ValidationError(_('Please Create Membership Invoice')) + if self.invoice_id.payment_state != 'paid': + raise ValidationError(_('Membership Invoice is not paid.\nPlease Paid membership invoice and active the membership.')) + self.state = 'active' + + def action_cancel_membership(self): + self.state = 'cancel' + + def action_set_to_draft(self): + self.state = 'draft' + + @api.model + def create(self, vals): + res = super(DevMembership, self).create(vals) + sequence = self.env['ir.sequence'].next_by_code('seq.dev.membership') or 'New' + res.name = sequence + return res + + def unlink(self): + for rec in self: + if rec.state not in ('draft', 'cancel'): + raise UserError("You are not allowed to delete this record!!") + return super(DevMembership, self).unlink() + + def membership_send_by_mail(self): + self.ensure_one() + template_id = self.env['ir.model.data'].xmlid_to_res_id('dev_membership.template_membership', raise_if_not_found=False) + ctx = { + 'default_model': 'dev.membership', + 'default_res_id': self.ids[0], + 'default_use_template': bool(template_id), + 'default_template_id': template_id, + 'default_composition_mode': 'comment', + 'force_email': True, + } + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'mail.compose.message', + 'views': [(False, 'form')], + 'view_id': False, + 'target': 'new', + 'context': ctx, + } + + def membership_auto_expire(self): + current_date = datetime.now().date() + membership_ids = self.env['dev.membership'].search([('state', '=', 'active'), + ('to_date', '<', current_date)]) + template_id = self.env.ref('dev_membership.dev_membership_expired_mail_template') + for membership in membership_ids: + membership.state = 'expire' + template_id.send_mail(membership.id, force_send=True) + + def membership_reminder_email_cron(self): + membership_pool = self.env['dev.membership'] + tmpl_id = self.env.ref('dev_membership.dev_membership_expire_reminder_mail_template') + days_before = self.env['ir.config_parameter'].get_param('dev_membership.days_before') + if tmpl_id: + date = datetime.now().date() + relativedelta(days=int(days_before)) + membership_ids = membership_pool.search([('state', '=', 'active'), + ('to_date', '<=', date)]) + for membership in membership_ids: + tmpl_id.send_mail(membership.id, force_send=True) + return True + + 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, + 'invoice_line_ids': [ + (0, None, {'product_id': self.product_id.id, 'quantity': 1, 'price_unit': self.membership_fees, 'tax_ids': [(6, 0, self.product_id.taxes_id.ids)]}) + ] + } + invoice_id = self.env['account.move'].create(vals) + self.invoice_id = invoice_id and invoice_id.id or False + + + def view_invoice(self): + if self.invoice_id: + ctx = dict(create=False) + return { + 'type': 'ir.actions.act_window', + 'name': 'Invoice', + 'res_model': 'account.move', + 'domain': [('id', '=', self.invoice_id.id)], + 'view_mode': 'tree,form', + 'target': 'current', + 'context': ctx, + } + + + def view_membership(self): + if self.membership_id: + ctx = dict(create=False) + return { + 'type': 'ir.actions.act_window', + 'name': 'Membership', + 'res_model': 'dev.membership', + 'domain': [('id', '=', self.membership_id.id)], + 'view_mode': 'tree,form', + 'target': 'current', + 'context': ctx, + } + + + diff --git a/odex25_sales/dev_membership/models/product_template.py b/odex25_sales/dev_membership/models/product_template.py new file mode 100644 index 000000000..a4eba9e0e --- /dev/null +++ b/odex25_sales/dev_membership/models/product_template.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (). +# +# For Module Support : devintelle@gmail.com or Skype : devintelle +# +############################################################################## + +from odoo import fields, models + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + def view_membership(self): + ctx = dict(create=False) + return { + 'type': 'ir.actions.act_window', + 'name': 'Membership', + 'res_model': 'dev.membership', + 'domain': [('product_id.name', '=', self.name)], + 'view_mode': 'tree,form', + 'target': 'current', + 'context': ctx, + } + + def _get_membership_count(self): + for rec in self: + membership_count = self.env['dev.membership'].search_count([('product_id.name', '=', rec.name)]) + rec.membership_count = membership_count + + is_membership = fields.Boolean(string="Is Membership") + duration = fields.Integer(string="Duration") + interval = fields.Selection(string="Interval", selection=([('days', 'Days'), + ('month', 'Month'), + ('year', 'Year')]), default='month') + + membership_count = fields.Integer(string="Membership Count", compute="_get_membership_count") + + +class ProductProduct(models.Model): + _inherit = "product.product" + + def view_membership(self): + ctx = dict(create=False) + return { + 'type': 'ir.actions.act_window', + 'name': 'Membership', + 'res_model': 'dev.membership', + 'domain': [('product_id.name', '=', self.name)], + 'view_mode': 'tree,form', + 'target': 'current', + 'context': ctx, + } diff --git a/odex25_sales/dev_membership/models/res_config_settings.py b/odex25_sales/dev_membership/models/res_config_settings.py new file mode 100644 index 000000000..b670c5c94 --- /dev/null +++ b/odex25_sales/dev_membership/models/res_config_settings.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + days_before = fields.Integer(string='Days Before', config_parameter='dev_membership.days_before') diff --git a/odex25_sales/dev_membership/models/res_partner.py b/odex25_sales/dev_membership/models/res_partner.py new file mode 100644 index 000000000..1df3d6119 --- /dev/null +++ b/odex25_sales/dev_membership/models/res_partner.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (). +# +# For Module Support : devintelle@gmail.com or Skype : devintelle +# +############################################################################## + +from odoo import fields, models, api +from datetime import datetime + + +class PartnerExtended(models.Model): + _inherit = 'res.partner' + + 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') + is_membership_expire = fields.Boolean('Expire Membership', compute='check_active_membership') + memebership_status = fields.Char('Membership Status', compute='check_memebership_status') + + def check_memebership_status(self): + for partner in self: + partner.memebership_status = '' + if partner.membership_count == 0: + partner.memebership_status = 'No Membership' + else: + 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: + partner.active_membership_id = False + partner.is_membership_expire = False + if partner.membership_count > 0: + c_date = datetime.now().date() + membership_id = self.env['dev.membership'].sudo().search([('partner_id', '=', partner.id), + ('state', '=', 'active'), + ('from_date', '<=', c_date), + ('to_date', '>=', c_date)], limit=1) + if membership_id: + partner.active_membership_id = membership_id and membership_id.id or False + else: + partner.is_membership_expire = True + + def _get_membership_count(self): + for rec in self: + membership_count = self.env['dev.membership'].search_count([('partner_id', '=', rec.id)]) + rec.membership_count = membership_count + + def view_membership(self): + ctx = dict(create=False, search_default_state=1) + return { + 'type': 'ir.actions.act_window', + 'name': 'Membership', + 'res_model': 'dev.membership', + 'domain': [('partner_id', '=', self.id)], + 'view_mode': 'tree,form', + 'target': 'current', + 'context': ctx, + } diff --git a/odex25_sales/dev_membership/report/__init__.py b/odex25_sales/dev_membership/report/__init__.py new file mode 100644 index 000000000..45d16f756 --- /dev/null +++ b/odex25_sales/dev_membership/report/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (). +# +# For Module Support : devintelle@gmail.com or Skype : devintelle +# +############################################################################## + +from . import print_membership + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex25_sales/dev_membership/report/print_membership.py b/odex25_sales/dev_membership/report/print_membership.py new file mode 100644 index 000000000..21cc64a45 --- /dev/null +++ b/odex25_sales/dev_membership/report/print_membership.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (). +# +# For Module Support : devintelle@gmail.com or Skype : devintelle +# +############################################################################## + +from odoo import models, api +from datetime import datetime + + +class PrintMembership(models.AbstractModel): + _name = 'report.dev_membership.membership_card' + _description="Membership Report" + + def get_date(self, date): + date = date.strftime('%d-%m-%Y') + return date + + def _get_report_values(self, docids, data=None): + docs = self.env['dev.membership'].browse(docids) + return { + 'doc_ids': docs.ids, + 'doc_model': 'dev.membership', + 'docs': docs, + 'get_date': self.get_date, + } + + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex25_sales/dev_membership/report/print_membership_menu.xml b/odex25_sales/dev_membership/report/print_membership_menu.xml new file mode 100644 index 000000000..5e572cc40 --- /dev/null +++ b/odex25_sales/dev_membership/report/print_membership_menu.xml @@ -0,0 +1,37 @@ + + + + + + Membership Card + + custom + 130 + + 172 + + Portrait + 25 + 7 + 0 + 0 + + 25 + 90 + + + + Print Membership + dev.membership + qweb-pdf + dev_membership.membership_card + dev_membership.membership_card + + report + + + \ No newline at end of file diff --git a/odex25_sales/dev_membership/report/print_membership_template.xml b/odex25_sales/dev_membership/report/print_membership_template.xml new file mode 100644 index 000000000..708fd5abf --- /dev/null +++ b/odex25_sales/dev_membership/report/print_membership_template.xml @@ -0,0 +1,77 @@ + + + + + + + diff --git a/odex25_sales/dev_membership/security/ir.model.access.csv b/odex25_sales/dev_membership/security/ir.model.access.csv new file mode 100644 index 000000000..3c5ddaeb1 --- /dev/null +++ b/odex25_sales/dev_membership/security/ir.model.access.csv @@ -0,0 +1,9 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink + +access_dev_membership_base,dev_membership.base,model_dev_membership,base.group_user,1,0,0,0 +access_renew_membership_base,renew_membership.base,model_renew_membership,base.group_user,1,0,0,0 +access_dev_membership_user,dev.membership.user,model_dev_membership,group_membership_user,1,1,1,1 +access_dev_membership_manager,dev.membership.manager,model_dev_membership,group_membership_manager,1,1,1,1 +access_renew_membership_user,renew.membership.user,model_renew_membership,group_membership_user,1,1,1,1 +access_renew_membership_manager,renew.membership.manager,model_renew_membership,group_membership_manager,1,1,1,1 + diff --git a/odex25_sales/dev_membership/security/security.xml b/odex25_sales/dev_membership/security/security.xml new file mode 100644 index 000000000..0d95945b7 --- /dev/null +++ b/odex25_sales/dev_membership/security/security.xml @@ -0,0 +1,42 @@ + + + + + Dev Membership Record Rule + + + [('company_id', 'in', company_ids)] + + + + + Membership + 0 + + + + User + + + + Manager + + + + + + + View Own Membership + + ['|',('user_id','=',user.id),('user_id','=',False)] + + + + + View All Membership + + [(1,'=',1)] + + + + diff --git a/odex25_sales/dev_membership/static/description/banners/dev_account_cancel_rights.png b/odex25_sales/dev_membership/static/description/banners/dev_account_cancel_rights.png new file mode 100644 index 000000000..c926b82a6 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/banners/dev_account_cancel_rights.png differ diff --git a/odex25_sales/dev_membership/static/description/banners/dev_hr_loan.png b/odex25_sales/dev_membership/static/description/banners/dev_hr_loan.png new file mode 100644 index 000000000..c04054607 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/banners/dev_hr_loan.png differ diff --git a/odex25_sales/dev_membership/static/description/banners/dev_public_holiday.png b/odex25_sales/dev_membership/static/description/banners/dev_public_holiday.png new file mode 100644 index 000000000..76d088a8e Binary files /dev/null and b/odex25_sales/dev_membership/static/description/banners/dev_public_holiday.png differ diff --git a/odex25_sales/dev_membership/static/description/banners/dev_purchase_down_payment.png b/odex25_sales/dev_membership/static/description/banners/dev_purchase_down_payment.png new file mode 100644 index 000000000..a82b0c9d4 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/banners/dev_purchase_down_payment.png differ diff --git a/odex25_sales/dev_membership/static/description/banners/dev_rma.png b/odex25_sales/dev_membership/static/description/banners/dev_rma.png new file mode 100644 index 000000000..f92456095 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/banners/dev_rma.png differ diff --git a/odex25_sales/dev_membership/static/description/banners/dev_user_quick_setup.png b/odex25_sales/dev_membership/static/description/banners/dev_user_quick_setup.png new file mode 100644 index 000000000..099efa830 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/banners/dev_user_quick_setup.png differ diff --git a/odex25_sales/dev_membership/static/description/icon.png b/odex25_sales/dev_membership/static/description/icon.png new file mode 100644 index 000000000..33d31b629 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/icon.png differ diff --git a/odex25_sales/dev_membership/static/description/images/Redirect.png b/odex25_sales/dev_membership/static/description/images/Redirect.png new file mode 100644 index 000000000..2e853bb36 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/Redirect.png differ diff --git a/odex25_sales/dev_membership/static/description/images/arrow.png b/odex25_sales/dev_membership/static/description/images/arrow.png new file mode 100644 index 000000000..8dbbbb277 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/arrow.png differ diff --git a/odex25_sales/dev_membership/static/description/images/customization.png b/odex25_sales/dev_membership/static/description/images/customization.png new file mode 100644 index 000000000..d029e0bb8 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/customization.png differ diff --git a/odex25_sales/dev_membership/static/description/images/development.png b/odex25_sales/dev_membership/static/description/images/development.png new file mode 100644 index 000000000..4337ab326 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/development.png differ diff --git a/odex25_sales/dev_membership/static/description/images/fb.png b/odex25_sales/dev_membership/static/description/images/fb.png new file mode 100644 index 000000000..7916a610e Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/fb.png differ diff --git a/odex25_sales/dev_membership/static/description/images/implementation.png b/odex25_sales/dev_membership/static/description/images/implementation.png new file mode 100644 index 000000000..1f8f86a53 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/implementation.png differ diff --git a/odex25_sales/dev_membership/static/description/images/in.png b/odex25_sales/dev_membership/static/description/images/in.png new file mode 100644 index 000000000..72a49839b Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/in.png differ diff --git a/odex25_sales/dev_membership/static/description/images/instagram.png b/odex25_sales/dev_membership/static/description/images/instagram.png new file mode 100644 index 000000000..c014a4b70 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/instagram.png differ diff --git a/odex25_sales/dev_membership/static/description/images/logo.png b/odex25_sales/dev_membership/static/description/images/logo.png new file mode 100644 index 000000000..df7a9352e Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/logo.png differ diff --git a/odex25_sales/dev_membership/static/description/images/mail.png b/odex25_sales/dev_membership/static/description/images/mail.png new file mode 100644 index 000000000..bb3b8e460 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/mail.png differ diff --git a/odex25_sales/dev_membership/static/description/images/pinterest.png b/odex25_sales/dev_membership/static/description/images/pinterest.png new file mode 100644 index 000000000..855db9add Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/pinterest.png differ diff --git a/odex25_sales/dev_membership/static/description/images/rocket.png b/odex25_sales/dev_membership/static/description/images/rocket.png new file mode 100644 index 000000000..09bb4b78d Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/rocket.png differ diff --git a/odex25_sales/dev_membership/static/description/images/skype.png b/odex25_sales/dev_membership/static/description/images/skype.png new file mode 100644 index 000000000..2c916e1fa Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/skype.png differ diff --git a/odex25_sales/dev_membership/static/description/images/support.png b/odex25_sales/dev_membership/static/description/images/support.png new file mode 100644 index 000000000..c3b0c85fb Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/support.png differ diff --git a/odex25_sales/dev_membership/static/description/images/training.png b/odex25_sales/dev_membership/static/description/images/training.png new file mode 100644 index 000000000..0f360acae Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/training.png differ diff --git a/odex25_sales/dev_membership/static/description/images/tube.png b/odex25_sales/dev_membership/static/description/images/tube.png new file mode 100644 index 000000000..77d6c9f37 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/tube.png differ diff --git a/odex25_sales/dev_membership/static/description/images/tweet.png b/odex25_sales/dev_membership/static/description/images/tweet.png new file mode 100644 index 000000000..2687d6972 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/tweet.png differ diff --git a/odex25_sales/dev_membership/static/description/images/twitter.png b/odex25_sales/dev_membership/static/description/images/twitter.png new file mode 100644 index 000000000..ce7f2b066 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/twitter.png differ diff --git a/odex25_sales/dev_membership/static/description/images/wp.png b/odex25_sales/dev_membership/static/description/images/wp.png new file mode 100644 index 000000000..d4b5e9c81 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/wp.png differ diff --git a/odex25_sales/dev_membership/static/description/images/youtube.png b/odex25_sales/dev_membership/static/description/images/youtube.png new file mode 100644 index 000000000..ef73f68e3 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/images/youtube.png differ diff --git a/odex25_sales/dev_membership/static/description/index.html b/odex25_sales/dev_membership/static/description/index.html new file mode 100644 index 000000000..c738d9abd --- /dev/null +++ b/odex25_sales/dev_membership/static/description/index.html @@ -0,0 +1,653 @@ + + + + + + Membership Management, Membership subscription Plans + + + + + + + + + + + + + +
+
+ +
+

+ Membership Management +

+
+ +
+

+ Using Membership Management odoo application you can easily manage Membership. Define various membership products, membership plans, create + members and create their membership. +

+
+
+ + + +
+
+ + + +
+
+ +
+
Key Features
+
    +
  • + arrow + + Manage membership inside the odoo + +
  • +
  • + arrow + + Create and manage members + +
  • +
  • + arrow + + Create Membership Product, you can decide the period of membership here + it may be N number of Days, Months or Years + +
  • +
  • + arrow + + Create Membership for the member, select membership product there and duration of + membership will be automatically loaded based on membership product + +
  • +
  • + arrow + + Create Invoice for the membership + +
  • +
  • + arrow + + You can activate membership only when invoice is paid + +
  • +
  • + arrow + + Membership will be automatically expire on its expiry date + +
  • +
  • + arrow + + Once membership is expired you can Renew membership from there + +
  • +
  • + arrow + + Separate menus provided for Active and Expire membership + +
  • +
  • + arrow + + Send membership into the email to the Member + +
  • +
  • + arrow + + Print membership as PDF Report + +
  • +
  • + arrow + + Configure membership expiry before days so it will send notification email to the + member before N number of days of expiry date of membership + +
  • +
  • + arrow + + Role of Users: +
      +
    • Membership > User
    • +
    • Membership > Manager
    • +
    +
    +
  • +
+
+ + +
+
+
    +
  • + + Create Members + arrow + +
  • +
  • + + Configure Membership Products + arrow + arrow + +
  • +
  • + + Create Membership from here + arrow + arrow + +
  • +
  • + + Confirm Membership + arrow + +
  • +
  • + + Create Membership Invoice + arrow + arrow + arrow + +
  • +
  • + + Activate Membership from here once invoice is paid + arrow + +
  • +
  • + + Renew expired membership from here + arrow + arrow + +
  • +
  • + + Membership is renewed + arrow + +
  • +
  • + + Access all membership from here + arrow + +
  • +
  • + + Access active membership from here + arrow + +
  • +
  • + + Access expired membership from here + arrow + +
  • +
  • + + Configure membership expiry reminder before days + arrow + +
  • +
  • + + Membership expiry email sample + arrow + +
  • +
  • + + Print membership as pdf report + arrow + arrow + +
  • +
  • + + Send membership by email to member + arrow + arrow + +
  • +
+
+
+
+ + +
+
+
+ Latest Release 0.1 - 2nd January 2023 +
+
    +
  • + arrow + Membership Management +
  • +
  • + arrow + Membership subscription Plans +
  • +
+
+
+ + +
+ +
+ + +
+
    +
  • + arrow +
    +
    Is this app compatible with Odoo Enterprise?
    + Yes, our app works with Odoo Enterprise as well as Community. +
    +
  • +
+
+ + +
+ + + + + + + + + + +
+ Support +
+
+ Not found +
+
+ + DevIntelle will provide FREE 90 days support for any doubt, queries, and bug fixing (excluding data recovery) or any type of issues related to this app. This is + applicable from the date of purchase + + +
+
+ +
+
+
+
+ + + + + + + +
+ + + + + + diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership1.png b/odex25_sales/dev_membership/static/description/screens/dev_membership1.png new file mode 100644 index 000000000..5b2aa8f93 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership1.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership10.png b/odex25_sales/dev_membership/static/description/screens/dev_membership10.png new file mode 100644 index 000000000..bbe9da6b4 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership10.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership12.png b/odex25_sales/dev_membership/static/description/screens/dev_membership12.png new file mode 100644 index 000000000..2edbb0970 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership12.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership13.png b/odex25_sales/dev_membership/static/description/screens/dev_membership13.png new file mode 100644 index 000000000..de9ae5582 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership13.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership14.png b/odex25_sales/dev_membership/static/description/screens/dev_membership14.png new file mode 100644 index 000000000..9f898fff7 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership14.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership15.png b/odex25_sales/dev_membership/static/description/screens/dev_membership15.png new file mode 100644 index 000000000..8de6cdb1a Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership15.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership16.png b/odex25_sales/dev_membership/static/description/screens/dev_membership16.png new file mode 100644 index 000000000..72b43b08e Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership16.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership17.png b/odex25_sales/dev_membership/static/description/screens/dev_membership17.png new file mode 100644 index 000000000..f5c49da1f Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership17.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership18.png b/odex25_sales/dev_membership/static/description/screens/dev_membership18.png new file mode 100644 index 000000000..96805c0f3 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership18.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership19.png b/odex25_sales/dev_membership/static/description/screens/dev_membership19.png new file mode 100644 index 000000000..ef7550005 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership19.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership2.png b/odex25_sales/dev_membership/static/description/screens/dev_membership2.png new file mode 100644 index 000000000..e3980de5e Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership2.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership20.png b/odex25_sales/dev_membership/static/description/screens/dev_membership20.png new file mode 100644 index 000000000..91394f245 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership20.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership21.png b/odex25_sales/dev_membership/static/description/screens/dev_membership21.png new file mode 100644 index 000000000..152fa81a3 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership21.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership22.png b/odex25_sales/dev_membership/static/description/screens/dev_membership22.png new file mode 100644 index 000000000..295922a14 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership22.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership23.png b/odex25_sales/dev_membership/static/description/screens/dev_membership23.png new file mode 100644 index 000000000..ede038fd2 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership23.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership3.png b/odex25_sales/dev_membership/static/description/screens/dev_membership3.png new file mode 100644 index 000000000..45c07e630 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership3.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership4.png b/odex25_sales/dev_membership/static/description/screens/dev_membership4.png new file mode 100644 index 000000000..0587c1e89 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership4.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership5.png b/odex25_sales/dev_membership/static/description/screens/dev_membership5.png new file mode 100644 index 000000000..2d11cb7a2 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership5.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership6.png b/odex25_sales/dev_membership/static/description/screens/dev_membership6.png new file mode 100644 index 000000000..4e7cc088e Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership6.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership7.png b/odex25_sales/dev_membership/static/description/screens/dev_membership7.png new file mode 100644 index 000000000..a378cf312 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership7.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership8.png b/odex25_sales/dev_membership/static/description/screens/dev_membership8.png new file mode 100644 index 000000000..9cc70c6c4 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership8.png differ diff --git a/odex25_sales/dev_membership/static/description/screens/dev_membership9.png b/odex25_sales/dev_membership/static/description/screens/dev_membership9.png new file mode 100644 index 000000000..3efd7dca8 Binary files /dev/null and b/odex25_sales/dev_membership/static/description/screens/dev_membership9.png differ diff --git a/odex25_sales/dev_membership/views/dev_membership.xml b/odex25_sales/dev_membership/views/dev_membership.xml new file mode 100644 index 000000000..3bd0efb5b --- /dev/null +++ b/odex25_sales/dev_membership/views/dev_membership.xml @@ -0,0 +1,229 @@ + + + + + view.dev.membership.tree + dev.membership + + + + + + + + + + + + + + + + + view.dev.membership.form + dev.membership + +
+
+
+ +
+ + +
+

+ +

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

+

+ +
+
+
+ + + +
+
+
+
+ + + + view.dev.membership.kanban + dev.membership + + + + + + + + + + + +
+
+
+
+
+
+ +
+
+ + + Membership + +
+ - +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + search.dev.membership + dev.membership + + + + + + + + + + + + + + + + + + + + Memberships + ir.actions.act_window + dev.membership + kanban,tree,form + + + + + Active Memberships + ir.actions.act_window + dev.membership + kanban,tree,form + [('state', '=', 'active')] + + + + + Expire Memberships + ir.actions.act_window + dev.membership + kanban,tree,form + [('state', '=', 'expire')] + + + + + + + + +
diff --git a/odex25_sales/dev_membership/views/main_menu.xml b/odex25_sales/dev_membership/views/main_menu.xml new file mode 100644 index 000000000..f3cd0cc3e --- /dev/null +++ b/odex25_sales/dev_membership/views/main_menu.xml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/odex25_sales/dev_membership/views/partner_extended.xml b/odex25_sales/dev_membership/views/partner_extended.xml new file mode 100644 index 000000000..7bd6e2c59 --- /dev/null +++ b/odex25_sales/dev_membership/views/partner_extended.xml @@ -0,0 +1,149 @@ + + + + + view.dev.res.partner.member.tree + res.partner + + + + + + + + + + + + + dev.res.partner.member.kanban + res.partner + 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+ +
+
+ + +