diff --git a/account_payment_approval/README.rst b/account_payment_approval/README.rst new file mode 100644 index 000000000..9cda493e2 --- /dev/null +++ b/account_payment_approval/README.rst @@ -0,0 +1,18 @@ +Payment Approval v14 +==================== +Enables to use the approval feature in customer and vendor payments. + +Installation +============ +No additional files neeeded. + +Configuration +============= + +No configurations needed. + +Credits +======= +Developer: v13.0 Mashood K U @ cybrosys, odoo@cybrosys.com + v14.0 Minhaj T @ cybrosys, odoo@cybrosys.com + diff --git a/account_payment_approval/__init__.py b/account_payment_approval/__init__.py new file mode 100644 index 000000000..9d876ea62 --- /dev/null +++ b/account_payment_approval/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from . import models diff --git a/account_payment_approval/__manifest__.py b/account_payment_approval/__manifest__.py new file mode 100644 index 000000000..cb7c787b4 --- /dev/null +++ b/account_payment_approval/__manifest__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +{ + 'name': 'Payment Approvals', + 'version': '14.0.1.0.0', + 'category': 'Accounting', + 'summary': """ This modules enables approval feature in the payment.""", + 'description': """This modules enables approval feature in the payment. """, + 'author': ' Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['account'], + 'data': [ + 'views/res_config_settings_views.xml', + 'views/account_payment_view.xml', + ], + 'license': 'LGPL-3', + 'images': ['static/description/banner.png'], + 'installable': True, + 'auto_install': False, + 'application': True, +} + diff --git a/account_payment_approval/doc/RELEASE_NOTES.md b/account_payment_approval/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..e588144c2 --- /dev/null +++ b/account_payment_approval/doc/RELEASE_NOTES.md @@ -0,0 +1,7 @@ +## Module + +#### 27.10.2020 +#### Version 14.0.1.0.0 +##### ADD +- Initial commit for Payment Approval + diff --git a/account_payment_approval/models/__init__.py b/account_payment_approval/models/__init__.py new file mode 100644 index 000000000..0d61bd07a --- /dev/null +++ b/account_payment_approval/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from . import account_payment +from . import res_config_settings diff --git a/account_payment_approval/models/account_payment.py b/account_payment_approval/models/account_payment.py new file mode 100644 index 000000000..d7df7d289 --- /dev/null +++ b/account_payment_approval/models/account_payment.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from odoo import models, fields, _ +from odoo.exceptions import UserError, ValidationError + + +class AccountMove(models.Model): + _inherit = "account.move" + state = fields.Selection(selection_add=[('waiting_approval', 'Waiting For Approval'), + ('approved', 'Approved'), + ('rejected', 'Rejected')], + ondelete={'waiting_approval': 'set default', 'approved': 'set default', + 'rejected': 'set default'}) + + +class AccountPayment(models.Model): + _inherit = "account.payment" + _inherits = {'account.move': 'move_id'} + + def _check_is_approver(self): + approval = self.env['ir.config_parameter'].sudo().get_param( + 'account_payment_approval.payment_approval') + approver_id = int(self.env['ir.config_parameter'].sudo().get_param( + 'account_payment_approval.approval_user_id')) + self.is_approver = True if self.env.user.id == approver_id and approval else False + + is_approver = fields.Boolean(compute=_check_is_approver, readonly=True) + + def action_post(self): + """Overwrites the _post() to validate the payment in the 'approved' stage too. + Currently Odoo allows payment posting only in draft stage. + """ + validation = self._check_payment_approval() + if validation: + if self.state not in ('draft', 'approved'): + raise UserError(_("Only a draft or approved payment can be posted.")) + + if any(inv.state != 'posted' for inv in self.reconciled_invoice_ids): + raise ValidationError(_("The payment cannot be processed because the invoice is not open!")) + self.move_id._post(soft=False) + + def _check_payment_approval(self): + if self.state == "draft": + first_approval = self.env['ir.config_parameter'].sudo().get_param( + 'account_payment_approval.payment_approval') + if first_approval: + amount = float(self.env['ir.config_parameter'].sudo().get_param( + 'account_payment_approval.approval_amount')) + payment_currency_id = int(self.env['ir.config_parameter'].sudo().get_param( + 'account_payment_approval.approval_currency_id')) + payment_amount = self.amount + if payment_currency_id: + if self.currency_id and self.currency_id.id != payment_currency_id: + currency_id = self.env['res.currency'].browse(payment_currency_id) + payment_amount = self.currency_id._convert( + self.amount, currency_id, self.company_id, + self.date or fields.Date.today(), round=True) + if payment_amount > amount: + self.write({ + 'state': 'waiting_approval' + }) + return False + return True + + def approve_transfer(self): + if self.is_approver: + self.write({ + 'state': 'approved' + }) + + def reject_transfer(self): + self.write({ + 'state': 'rejected' + }) diff --git a/account_payment_approval/models/res_config_settings.py b/account_payment_approval/models/res_config_settings.py new file mode 100644 index 000000000..05ef9d260 --- /dev/null +++ b/account_payment_approval/models/res_config_settings.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + def _get_account_manager_ids(self): + user_ids = self.env['res.users'].search([]) + account_manager_ids = user_ids.filtered(lambda l: l.has_group('account.group_account_manager')) + return [('id', 'in', account_manager_ids.ids)] + + payment_approval = fields.Boolean('Payment Approval', config_parameter='account_payment_approval.payment_approval') + approval_user_id = fields.Many2one('res.users', string="Payment Approver", required=False, + domain=_get_account_manager_ids, + config_parameter='account_payment_approval.approval_user_id') + approval_amount = fields.Float('Minimum Approval Amount', config_parameter='account_payment_approval.approval_amount', + help="If amount is 0.00, All the payments go through approval.") + approval_currency_id = fields.Many2one('res.currency', string='Approval Currency', + config_parameter='account_payment_approval.approval_currency_id', + help="Converts the payment amount to this currency if chosen.") diff --git a/account_payment_approval/static/description/banner.png b/account_payment_approval/static/description/banner.png new file mode 100644 index 000000000..6a6372e77 Binary files /dev/null and b/account_payment_approval/static/description/banner.png differ diff --git a/account_payment_approval/static/description/icon.png b/account_payment_approval/static/description/icon.png new file mode 100644 index 000000000..fbd82106c Binary files /dev/null and b/account_payment_approval/static/description/icon.png differ diff --git a/account_payment_approval/static/description/images/banner-account-bank-book.png b/account_payment_approval/static/description/images/banner-account-bank-book.png new file mode 100644 index 000000000..088d9be88 Binary files /dev/null and b/account_payment_approval/static/description/images/banner-account-bank-book.png differ diff --git a/account_payment_approval/static/description/images/banner-account-cash-book.jpg b/account_payment_approval/static/description/images/banner-account-cash-book.jpg new file mode 100644 index 000000000..b7a48f2f4 Binary files /dev/null and b/account_payment_approval/static/description/images/banner-account-cash-book.jpg differ diff --git a/account_payment_approval/static/description/images/banner-account-day-book.png b/account_payment_approval/static/description/images/banner-account-day-book.png new file mode 100644 index 000000000..a3fced2e6 Binary files /dev/null and b/account_payment_approval/static/description/images/banner-account-day-book.png differ diff --git a/account_payment_approval/static/description/images/banner-account-recurring-payment.png b/account_payment_approval/static/description/images/banner-account-recurring-payment.png new file mode 100644 index 000000000..d7ed02cc9 Binary files /dev/null and b/account_payment_approval/static/description/images/banner-account-recurring-payment.png differ diff --git a/account_payment_approval/static/description/images/banner-accounting-kit.gif b/account_payment_approval/static/description/images/banner-accounting-kit.gif new file mode 100644 index 000000000..30b746d7f Binary files /dev/null and b/account_payment_approval/static/description/images/banner-accounting-kit.gif differ diff --git a/account_payment_approval/static/description/images/banner-customer-follow-ups.png b/account_payment_approval/static/description/images/banner-customer-follow-ups.png new file mode 100644 index 000000000..e2b85a997 Binary files /dev/null and b/account_payment_approval/static/description/images/banner-customer-follow-ups.png differ diff --git a/account_payment_approval/static/description/images/checked.png b/account_payment_approval/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/account_payment_approval/static/description/images/checked.png differ diff --git a/account_payment_approval/static/description/images/cybrosys.png b/account_payment_approval/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/account_payment_approval/static/description/images/cybrosys.png differ diff --git a/account_payment_approval/static/description/images/payment-approval-01.png b/account_payment_approval/static/description/images/payment-approval-01.png new file mode 100644 index 000000000..3db56a830 Binary files /dev/null and b/account_payment_approval/static/description/images/payment-approval-01.png differ diff --git a/account_payment_approval/static/description/images/payment-approval-02.png b/account_payment_approval/static/description/images/payment-approval-02.png new file mode 100644 index 000000000..d2dcfcd06 Binary files /dev/null and b/account_payment_approval/static/description/images/payment-approval-02.png differ diff --git a/account_payment_approval/static/description/images/payment-approval-03.png b/account_payment_approval/static/description/images/payment-approval-03.png new file mode 100644 index 000000000..e487c1915 Binary files /dev/null and b/account_payment_approval/static/description/images/payment-approval-03.png differ diff --git a/account_payment_approval/static/description/images/payment-approval-04.png b/account_payment_approval/static/description/images/payment-approval-04.png new file mode 100644 index 000000000..43f668311 Binary files /dev/null and b/account_payment_approval/static/description/images/payment-approval-04.png differ diff --git a/account_payment_approval/static/description/images/payment-approval-05.png b/account_payment_approval/static/description/images/payment-approval-05.png new file mode 100644 index 000000000..55d033f77 Binary files /dev/null and b/account_payment_approval/static/description/images/payment-approval-05.png differ diff --git a/account_payment_approval/static/description/images/payment-approval-06.png b/account_payment_approval/static/description/images/payment-approval-06.png new file mode 100644 index 000000000..048232579 Binary files /dev/null and b/account_payment_approval/static/description/images/payment-approval-06.png differ diff --git a/account_payment_approval/static/description/images/payment-approval-07.png b/account_payment_approval/static/description/images/payment-approval-07.png new file mode 100644 index 000000000..764b7efce Binary files /dev/null and b/account_payment_approval/static/description/images/payment-approval-07.png differ diff --git a/account_payment_approval/static/description/index.html b/account_payment_approval/static/description/index.html new file mode 100644 index 000000000..6d42cd6bc --- /dev/null +++ b/account_payment_approval/static/description/index.html @@ -0,0 +1,568 @@ +
+ cybrosys-logo
+
+
+
+

Payment Approval

+

Enables to use the approval feature in + customer and vendor payments. +

+
+

Key Highlights

+
    +
  • checkApproval stages in payments +
  • +
+
+
+
+
+
+
+
+ +
+
+ +

Overview

+
+

+ This module helps the accounting department to have a control over the payments. + It enables payment approval feature in the payment transaction. +

+
+
+ +

Dynamic Product Fields

+
+
    +
  • + + Approval stage in payment. +
  • +
  • + Can + Enable/disable payment approval from the settings. +
  • +
  • + Can + Approval feature can be applied based on the given amount. +
  • +
  • + Can + Currency wise amount specification. +
  • +
  • + Can + Quick access of the approval stages like Waiting For Approval, Approved, Rejected etc + from the filter window. +
  • + +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+
+ Odoo Industry
+
+
+

+ + Trading

+

+ Easily procure and sell your products.

+
+
+
+
+
+ Odoo Industry +
+
+
+

+ + Manufacturing

+

+ Plan, track and schedule your operations.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Restaurant

+

+ Run your bar or restaurant methodical.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + POS

+

+ Easy configuring and convivial selling.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + E-commerce & Website

+

+ Mobile friendly, awe-inspiring product pages.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Hotel Management

+

+ An all-inclusive hotel management application.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Education

+

+ A Collaborative platform for educational management.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + Service Management

+

+ Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please + let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/account_payment_approval/views/account_payment_view.xml b/account_payment_approval/views/account_payment_view.xml new file mode 100644 index 000000000..66b13f85a --- /dev/null +++ b/account_payment_approval/views/account_payment_view.xml @@ -0,0 +1,45 @@ + + + + account.payment.form + account.payment + + + + + + + + + + + view.employee.form + hr.employee + + +
+ +
+
+
+
+
\ No newline at end of file diff --git a/employee_late_check_in/views/late_check_in_view.xml b/employee_late_check_in/views/late_check_in_view.xml new file mode 100644 index 000000000..dd481a04b --- /dev/null +++ b/employee_late_check_in/views/late_check_in_view.xml @@ -0,0 +1,117 @@ + + + + + late.check_in.sequence + late.check_in + LC + + + 5 + + + + + + + late.check_in.form + late.check_in + +
+
+ +
+ +
+

+ +

+
+ + + + + + + + + + + +
+
+
+
+ + + late.check_in.search.view + late.check_in + + + + + + + + + + + + late.check_in.tree + late.check_in + + + + + + + + + + + + + + + Late Check-in + late.check_in + tree,form + { + 'search_default_group_employee': 1, + } + + + + + + + + + late_check_in.Inherited.View + hr.payslip + + + + + + + + + +
+
diff --git a/employee_late_check_in/views/res_config_settings.xml b/employee_late_check_in/views/res_config_settings.xml new file mode 100644 index 000000000..6a5c7ce0c --- /dev/null +++ b/employee_late_check_in/views/res_config_settings.xml @@ -0,0 +1,75 @@ + + + + + Late Check-in Configurations + res.config.settings + + + + +

Late Check-in

+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/employee_vehicle_request/README.rst b/employee_vehicle_request/README.rst new file mode 100644 index 000000000..32f3a3d12 --- /dev/null +++ b/employee_vehicle_request/README.rst @@ -0,0 +1,41 @@ +Employee Vehicle Request +======================== +This module is used for manage vehicle requests from employee. +This module also checking the vehicle availability at the requested time slot + +Configuration +============= +* No additional configurations needed + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developers: Nilmar Shereef @ Cybrosys, odoo@cybrosys.com + Niyas Raphy @cybrosys, odoo@cybrosys.com + Yadhukrishna K @cybrosys, odoo@cybrosys.com + Muhammed Nafih @cybrosys, odoo@cybrosys.com + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com +* Website : https://cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit `Our Website `__ + +Further information +=================== +HTML Description: ``__ diff --git a/employee_vehicle_request/__init__.py b/employee_vehicle_request/__init__.py new file mode 100644 index 000000000..48441876a --- /dev/null +++ b/employee_vehicle_request/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Nilmar Shereef @ Cybrosys, (odoo@cybrosys.com) +# Niyas Raphy @ Cybrosys, (odoo@cybrosys.com) +# Yadhukrishna @ Cybrosys, (odoo@cybrosys.com) +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import models diff --git a/employee_vehicle_request/__manifest__.py b/employee_vehicle_request/__manifest__.py new file mode 100644 index 000000000..e6ba1c2e9 --- /dev/null +++ b/employee_vehicle_request/__manifest__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Nilmar Shereef @ Cybrosys, (odoo@cybrosys.com) +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +{ + 'name': 'Employee Vehicle Request', + 'version': '14.0.1.0.0', + 'summary': """Manage Vehicle Requests From Employee""", + 'description': """This module is used for manage vehicle requests from employee. + This module also checking the vehicle availability at the requested time slot.""", + 'category': "Generic Modules/Human Resources", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['base', 'hr', 'fleet'], + 'data': [ + 'data/data.xml', + 'security/security.xml', + 'security/ir.model.access.csv', + 'views/employee_fleet_view.xml', + ], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'demo': [], + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/employee_vehicle_request/data/data.xml b/employee_vehicle_request/data/data.xml new file mode 100644 index 000000000..1a6b2294d --- /dev/null +++ b/employee_vehicle_request/data/data.xml @@ -0,0 +1,17 @@ + + + + + + User can only see his/her vehicle + + + + + + + [] + + + + \ No newline at end of file diff --git a/employee_vehicle_request/doc/RELEASE_NOTES.md b/employee_vehicle_request/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..40375e799 --- /dev/null +++ b/employee_vehicle_request/doc/RELEASE_NOTES.md @@ -0,0 +1,5 @@ +## Module + +#### 12.11.2020 +#### Version 14.0.1.0.0 +#### ADD diff --git a/employee_vehicle_request/models/__init__.py b/employee_vehicle_request/models/__init__.py new file mode 100644 index 000000000..3f50c1a7d --- /dev/null +++ b/employee_vehicle_request/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Nilmar Shereef @ Cybrosys, (odoo@cybrosys.com) +# Niyas Raphy @ Cybrosys, (odoo@cybrosys.com) +# Yadhukrishna @ Cybrosys, (odoo@cybrosys.com) +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +# -*- coding: utf-8 -*- + +from . import employee_fleet diff --git a/employee_vehicle_request/models/employee_fleet.py b/employee_vehicle_request/models/employee_fleet.py new file mode 100644 index 000000000..e3fe399a1 --- /dev/null +++ b/employee_vehicle_request/models/employee_fleet.py @@ -0,0 +1,176 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Nilmar Shereef @ Cybrosys, (odoo@cybrosys.com) +# Niyas Raphy @ Cybrosys, (odoo@cybrosys.com) +# Yadhukrishna @ Cybrosys, (odoo@cybrosys.com) +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +# -*- coding: utf-8 -*- + +from datetime import datetime +from odoo import models, fields, api, _ +from odoo.exceptions import UserError + + +class FleetReservedTime(models.Model): + _name = "fleet.reserved" + _description = "Reserved Time" + + employee = fields.Many2one('hr.employee', string='Employee') + date_from = fields.Datetime(string='Reserved Date From') + date_to = fields.Datetime(string='Reserved Date To') + reserved_obj = fields.Many2one('fleet.vehicle') + + +class FleetVehicleInherit(models.Model): + _inherit = 'fleet.vehicle' + + check_availability = fields.Boolean(default=True, copy=False) + reserved_time = fields.One2many('fleet.reserved', 'reserved_obj', String='Reserved Time', readonly=1, + ondelete='cascade') + + +class EmployeeFleet(models.Model): + _name = 'employee.fleet' + _description = 'Employee Vehicle Request' + _inherit = 'mail.thread' + + @api.model + def create(self, vals): + vals['name'] = self.env['ir.sequence'].next_by_code('employee.fleet') + return super(EmployeeFleet, self).create(vals) + + def send(self): + if self.date_from and self.date_to: + fleet_obj = self.env['fleet.vehicle'].search([]) + check_availability = 0 + for i in fleet_obj: + for each in i.reserved_time: + if each.date_from <= self.date_from <= each.date_to: + check_availability = 1 + elif self.date_from < each.date_from: + if each.date_from <= self.date_to <= each.date_to: + check_availability = 1 + elif self.date_to > each.date_to: + check_availability = 1 + else: + check_availability = 0 + else: + check_availability = 0 + if check_availability == 0: + reserved_id = self.fleet.reserved_time.create({'employee': self.employee.id, + 'date_from': self.date_from, + 'date_to': self.date_to, + 'reserved_obj': self.fleet.id, + }) + self.write({'reserved_fleet_id': reserved_id.id}) + self.state = 'waiting' + else: + raise UserError(_('Sorry This vehicle is already requested by another employee')) + + def approve(self): + # self.fleet.fleet_status = True + self.state = 'confirm' + mail_content = _('Hi %s,
Your vehicle request for the reference %s is approved.') % \ + (self.employee.name, self.name) + main_content = { + 'subject': _('%s: Approved') % self.name, + 'author_id': self.env.user.partner_id.id, + 'body_html': mail_content, + 'email_to': self.employee.work_email, + } + mail_id = self.env['mail.mail'].create(main_content) + mail_id.mail_message_id.body = mail_content + mail_id.send() + if self.employee.user_id: + mail_id.mail_message_id.write({'needaction_partner_ids': [(4, self.employee.user_id.partner_id.id)]}) + mail_id.mail_message_id.write({'partner_ids': [(4, self.employee.user_id.partner_id.id)]}) + + def reject(self): + self.reserved_fleet_id.unlink() + self.state = 'reject' + mail_content = _('Hi %s,
Sorry, Your vehicle request for the reference %s is Rejected.') % \ + (self.employee.name, self.name) + + main_content = { + 'subject': _('%s: Approved') % self.name, + 'author_id': self.env.user.partner_id.id, + 'body_html': mail_content, + 'email_to': self.employee.work_email, + } + mail_id = self.env['mail.mail'].create(main_content) + mail_id.mail_message_id.body = mail_content + mail_id.send() + if self.employee.user_id: + mail_id.mail_message_id.write({'needaction_partner_ids': [(4, self.employee.user_id.partner_id.id)]}) + mail_id.mail_message_id.write({'partner_ids': [(4, self.employee.user_id.partner_id.id)]}) + + def cancel(self): + if self.reserved_fleet_id: + self.reserved_fleet_id.unlink() + self.state = 'cancel' + + def returned(self): + self.reserved_fleet_id.unlink() + self.returned_date = fields.datetime.now() + self.state = 'return' + + @api.constrains('date_rom', 'date_to') + def onchange_date_to(self): + for each in self: + if each.date_from > each.date_to: + raise UserError(_('Date To must be greater than Date From')) + + @api.onchange('date_from', 'date_to') + def check_availability(self): + if self.date_from and self.date_to: + self.fleet = '' + fleet_obj = self.env['fleet.vehicle'].search([]) + for i in fleet_obj: + for each in i.reserved_time: + if each.date_from <= self.date_from <= each.date_to: + i.write({'check_availability': False}) + elif self.date_from < each.date_from: + if each.date_from <= self.date_to <= each.date_to: + i.write({'check_availability': False}) + elif self.date_to > each.date_to: + i.write({'check_availability': False}) + else: + i.write({'check_availability': True}) + else: + i.write({'check_availability': True}) + + reserved_fleet_id = fields.Many2one('fleet.reserved', invisible=1, copy=False) + name = fields.Char(string='Request Number', copy=False) + employee = fields.Many2one('hr.employee', string='Employee', required=1, readonly=True, + states={'draft': [('readonly', False)]}) + req_date = fields.Date(string='Requested Date', default=fields.Date.context_today, required=1, readonly=True, + states={'draft': [('readonly', False)]}, help="Requested Date") + fleet = fields.Many2one('fleet.vehicle', string='Vehicle', required=1, readonly=True, + states={'draft': [('readonly', False)]}) + date_from = fields.Datetime(string='From', required=1, readonly=True, + states={'draft': [('readonly', False)]}) + date_to = fields.Datetime(string='To', required=1, readonly=True, + states={'draft': [('readonly', False)]}) + returned_date = fields.Datetime(string='Returned Date', readonly=1) + purpose = fields.Text(string='Purpose', required=1, readonly=True, + states={'draft': [('readonly', False)]}, help="Purpose") + state = fields.Selection([('draft', 'Draft'), ('waiting', 'Waiting for Approval'), ('cancel', 'Cancel'), + ('confirm', 'Approved'), ('reject', 'Rejected'), ('return', 'Returned')], + string="State", default="draft") + diff --git a/employee_vehicle_request/security/ir.model.access.csv b/employee_vehicle_request/security/ir.model.access.csv new file mode 100644 index 000000000..6401ebdc3 --- /dev/null +++ b/employee_vehicle_request/security/ir.model.access.csv @@ -0,0 +1,7 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_fleet_reserved_employee,access.fleet.reserved.employee,model_fleet_reserved,base.group_user,1,1,1,0 +access_fleet_reserved_hr,access.fleet.reserved.hr,model_fleet_reserved,hr.group_hr_manager,1,1,1,1 +access_fleet_reserved_hr_user,access.fleet.reserved.hr.user,model_fleet_reserved,hr.group_hr_user,1,1,1,0 +access_employee_fleet_employee,access.employee.fleet.employee,model_employee_fleet,base.group_user,1,1,1,0 +access_employee_fleet_hr,access.employee.fleet.hr,model_employee_fleet,hr.group_hr_manager,1,1,1,1 +access_employee_fleet_hr_user,access.employee.fleet.hr.user,model_employee_fleet,hr.group_hr_user,1,1,1,0 diff --git a/employee_vehicle_request/security/security.xml b/employee_vehicle_request/security/security.xml new file mode 100644 index 000000000..cc4ef8001 --- /dev/null +++ b/employee_vehicle_request/security/security.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/employee_vehicle_request/static/description/banner.png b/employee_vehicle_request/static/description/banner.png new file mode 100644 index 000000000..7febb09f5 Binary files /dev/null and b/employee_vehicle_request/static/description/banner.png differ diff --git a/employee_vehicle_request/static/description/cybro_logo.png b/employee_vehicle_request/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/employee_vehicle_request/static/description/cybro_logo.png differ diff --git a/employee_vehicle_request/static/description/icon.png b/employee_vehicle_request/static/description/icon.png new file mode 100644 index 000000000..d0a5cb2a9 Binary files /dev/null and b/employee_vehicle_request/static/description/icon.png differ diff --git a/employee_vehicle_request/static/description/images/1veh req.png b/employee_vehicle_request/static/description/images/1veh req.png new file mode 100644 index 000000000..1c1ee047f Binary files /dev/null and b/employee_vehicle_request/static/description/images/1veh req.png differ diff --git a/employee_vehicle_request/static/description/images/1veh.png b/employee_vehicle_request/static/description/images/1veh.png new file mode 100644 index 000000000..4c0347ac7 Binary files /dev/null and b/employee_vehicle_request/static/description/images/1veh.png differ diff --git a/employee_vehicle_request/static/description/images/2veh req.png b/employee_vehicle_request/static/description/images/2veh req.png new file mode 100644 index 000000000..a78b3141c Binary files /dev/null and b/employee_vehicle_request/static/description/images/2veh req.png differ diff --git a/employee_vehicle_request/static/description/images/3veh req.png b/employee_vehicle_request/static/description/images/3veh req.png new file mode 100644 index 000000000..e99ae4813 Binary files /dev/null and b/employee_vehicle_request/static/description/images/3veh req.png differ diff --git a/employee_vehicle_request/static/description/images/4veh req.png b/employee_vehicle_request/static/description/images/4veh req.png new file mode 100644 index 000000000..8f9de5443 Binary files /dev/null and b/employee_vehicle_request/static/description/images/4veh req.png differ diff --git a/employee_vehicle_request/static/description/images/banner_lifeline_for_task.jpeg b/employee_vehicle_request/static/description/images/banner_lifeline_for_task.jpeg new file mode 100644 index 000000000..4a467ea22 Binary files /dev/null and b/employee_vehicle_request/static/description/images/banner_lifeline_for_task.jpeg differ diff --git a/employee_vehicle_request/static/description/images/banner_project_report_xls_pdf.png b/employee_vehicle_request/static/description/images/banner_project_report_xls_pdf.png new file mode 100644 index 000000000..3c430a7eb Binary files /dev/null and b/employee_vehicle_request/static/description/images/banner_project_report_xls_pdf.png differ diff --git a/employee_vehicle_request/static/description/images/banner_project_status_report.png b/employee_vehicle_request/static/description/images/banner_project_status_report.png new file mode 100644 index 000000000..d1b689710 Binary files /dev/null and b/employee_vehicle_request/static/description/images/banner_project_status_report.png differ diff --git a/employee_vehicle_request/static/description/images/banner_subtask.jpeg b/employee_vehicle_request/static/description/images/banner_subtask.jpeg new file mode 100644 index 000000000..f2b224110 Binary files /dev/null and b/employee_vehicle_request/static/description/images/banner_subtask.jpeg differ diff --git a/employee_vehicle_request/static/description/images/banner_task_deadline_reminder.jpeg b/employee_vehicle_request/static/description/images/banner_task_deadline_reminder.jpeg new file mode 100644 index 000000000..998679818 Binary files /dev/null and b/employee_vehicle_request/static/description/images/banner_task_deadline_reminder.jpeg differ diff --git a/employee_vehicle_request/static/description/images/banner_task_statusbar.jpeg b/employee_vehicle_request/static/description/images/banner_task_statusbar.jpeg new file mode 100644 index 000000000..2c57cbb7b Binary files /dev/null and b/employee_vehicle_request/static/description/images/banner_task_statusbar.jpeg differ diff --git a/employee_vehicle_request/static/description/images/checked.png b/employee_vehicle_request/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/employee_vehicle_request/static/description/images/checked.png differ diff --git a/employee_vehicle_request/static/description/images/cybrosys.png b/employee_vehicle_request/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/employee_vehicle_request/static/description/images/cybrosys.png differ diff --git a/employee_vehicle_request/static/description/index.html b/employee_vehicle_request/static/description/index.html new file mode 100644 index 000000000..5ea0f7302 --- /dev/null +++ b/employee_vehicle_request/static/description/index.html @@ -0,0 +1,316 @@ +
cybrosys-logo
+
+
+
+

Employee Vehicle Request

+

This Module Helps You To Manage Vehicle Requests From Employee

+
+

Key Highlights

+
    +
  • Employee can request for any vehicle
  • +
  • Checking availability of vehicles
  • +
  • Validation for send request
  • +
  • Validation for requested dates
  • +
  • Advanced search view
  • + +
+
+
+
+ +
+
+
+
+ +
+
+ +

Overview

+
+

+ Employee can request available vehicle for a time period. He should mention the time period and purpose. Then he can send this request to hr manager. Here also module checking the availability of vehicles

+
+
+ +

Employee Vehicle Request

+
+
    +
  • + Employee can request for any vehicle +
  • + +
  • + Checking availability of vehicles +
  • + +
  • + Validation for send request +
  • + +
  • + Validation for requested dates +
  • + +
  • + Advanced search view +
  • + +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/employee_vehicle_request/views/employee_fleet_view.xml b/employee_vehicle_request/views/employee_fleet_view.xml new file mode 100644 index 000000000..09fe8a169 --- /dev/null +++ b/employee_vehicle_request/views/employee_fleet_view.xml @@ -0,0 +1,122 @@ + + + + Vehicle Request Code + employee.fleet + + VR + + + + fleet.vehicle.form.inherit.view + fleet.vehicle + + + + + + + + + + + employee.fleet.form + employee.fleet + +
+
+
+ +

+ +

+ + + + + + + + + + + + + +
+
+ + +
+
+
+
+ + + employee.fleet.tree + employee.fleet + + + + + + + + + + + + + + employee.fleet.search + employee.fleet + + + + + + + + + + + + + + + + + + + + Vehicle Request + employee.fleet + tree,form + + +

+ Click to create a New Vehicle Request. +

+
+
+ + + +
\ No newline at end of file diff --git a/hr_zk_attendance/README.rst b/hr_zk_attendance/README.rst new file mode 100644 index 000000000..3d56fc1cf --- /dev/null +++ b/hr_zk_attendance/README.rst @@ -0,0 +1,38 @@ +Biometric Device Integration v14 +================================ +This Cybrosys's module integrates Odoo attendance with biometric device attendance. + +Features +======== +* Integrates biometric device(Face+Thumb) with HR attendance. +* Managing attendance automatically +* Keeps zk machine history in Odoo +* Option to configure multiple zk devices +* Option to clear all zk history from both device and Odoo + +Technical Notes +=============== +Used Libraries: + +*This integration is only applicable for the the device ZKteco model 'uFace 202' & 'iFace990' +* zklib +you can install zklib library using "sudo pip install zklib" + +Compatible Devices + +*ZKteco model 'uFace 202' +*ZKteco model 'iFace990' + +Author +======= +* Cybrosys Techno Solutions + +Credits +======= +Developer: Niyas Raphy @ Cybrosys, odoo@cybrosys.com V11 +Developer: Jesni Banu @ cybrosys, odoo@cybrosys.com V10 +Developer: Basith @ Cybrosys, odoo@cybrosys.com V12 +Developer: Varsha Vivek @ Cybrosys, odoo@cybrosys.com V13 +Developer: Ijaz Ahammed @ Cybrosys, odoo@cybrosys.com V14 +Developer: Mostafa Shokiel , mostafa.shokiel@gmail.com + diff --git a/hr_zk_attendance/__init__.py b/hr_zk_attendance/__init__.py new file mode 100644 index 000000000..9df61f52c --- /dev/null +++ b/hr_zk_attendance/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: cybrosys() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### +from . import models diff --git a/hr_zk_attendance/__manifest__.py b/hr_zk_attendance/__manifest__.py new file mode 100644 index 000000000..ec99d9e8c --- /dev/null +++ b/hr_zk_attendance/__manifest__.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: cybrosys() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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': 'Biometric Device Integration', + 'version': '14.0.1.0.0', + 'summary': """Integrating Biometric Device (Model: ZKteco uFace 202) With HR Attendance (Face + Thumb)""", + 'description': """This module integrates Odoo with the biometric device(Model: ZKteco uFace 202),odoo13,odd,hr,attendance""", + 'category': 'Generic Modules/Human Resources', + 'author': 'Cybrosys Techno Solutions, Mostafa Shokiel', + 'company': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['base_setup', 'hr_attendance'], + 'data': [ + 'security/ir.model.access.csv', + 'views/zk_machine_view.xml', + 'views/zk_machine_attendance_view.xml', + 'data/download_data.xml' + + ], + 'images': ['static/description/banner.gif'], + 'license': 'AGPL-3', + 'demo': [], + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/hr_zk_attendance/data/download_data.xml b/hr_zk_attendance/data/download_data.xml new file mode 100644 index 000000000..c4edd2e49 --- /dev/null +++ b/hr_zk_attendance/data/download_data.xml @@ -0,0 +1,14 @@ + + + + Download Data + + + 10 + minutes + -1 + + code + model.cron_download() + + diff --git a/hr_zk_attendance/doc/RELEASE_NOTES.md b/hr_zk_attendance/doc/RELEASE_NOTES.md new file mode 100755 index 000000000..8c79dded8 --- /dev/null +++ b/hr_zk_attendance/doc/RELEASE_NOTES.md @@ -0,0 +1,7 @@ +## Module + +#### 03.10.2020 +#### Version 14.0.1.0.0 +##### ADD +- Initial commit + diff --git a/hr_zk_attendance/models/__init__.py b/hr_zk_attendance/models/__init__.py new file mode 100644 index 000000000..8b72b54dd --- /dev/null +++ b/hr_zk_attendance/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: cybrosys() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### +from . import zk_machine +from . import machine_analysis +from . import zklib + diff --git a/hr_zk_attendance/models/machine_analysis.py b/hr_zk_attendance/models/machine_analysis.py new file mode 100644 index 000000000..a81a60647 --- /dev/null +++ b/hr_zk_attendance/models/machine_analysis.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: cybrosys() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### +from odoo import tools +from odoo import models, fields, api, _ + + +class HrEmployee(models.Model): + _inherit = 'hr.employee' + + device_id = fields.Char(string='Biometric Device ID') + + +class ZkMachine(models.Model): + _name = 'zk.machine.attendance' + _inherit = 'hr.attendance' + + @api.constrains('check_in', 'check_out', 'employee_id') + def _check_validity(self): + """overriding the __check_validity function for employee attendance.""" + pass + + device_id = fields.Char(string='Biometric Device ID') + punch_type = fields.Selection([('0', 'Check In'), + ('1', 'Check Out'), + ('2', 'Break Out'), + ('3', 'Break In'), + ('4', 'Overtime In'), + ('5', 'Overtime Out')], + string='Punching Type') + + attendance_type = fields.Selection([('1', 'Finger'), + ('15', 'Face'), + ('2','Type_2'), + ('3','Password'), + ('4','Card')], string='Category') + punching_time = fields.Datetime(string='Punching Time') + address_id = fields.Many2one('res.partner', string='Working Address') + + +class ReportZkDevice(models.Model): + _name = 'zk.report.daily.attendance' + _auto = False + _order = 'punching_day desc' + + name = fields.Many2one('hr.employee', string='Employee') + punching_day = fields.Datetime(string='Date') + address_id = fields.Many2one('res.partner', string='Working Address') + attendance_type = fields.Selection([('1', 'Finger'), + ('15', 'Face'), + ('2','Type_2'), + ('3','Password'), + ('4','Card')], + string='Category') + punch_type = fields.Selection([('0', 'Check In'), + ('1', 'Check Out'), + ('2', 'Break Out'), + ('3', 'Break In'), + ('4', 'Overtime In'), + ('5', 'Overtime Out')], string='Punching Type') + punching_time = fields.Datetime(string='Punching Time') + + def init(self): + tools.drop_view_if_exists(self._cr, 'zk_report_daily_attendance') + query = """ + create or replace view zk_report_daily_attendance as ( + select + min(z.id) as id, + z.employee_id as name, + z.write_date as punching_day, + z.address_id as address_id, + z.attendance_type as attendance_type, + z.punching_time as punching_time, + z.punch_type as punch_type + from zk_machine_attendance z + join hr_employee e on (z.employee_id=e.id) + GROUP BY + z.employee_id, + z.write_date, + z.address_id, + z.attendance_type, + z.punch_type, + z.punching_time + ) + """ + self._cr.execute(query) + + diff --git a/hr_zk_attendance/models/zk_machine.py b/hr_zk_attendance/models/zk_machine.py new file mode 100644 index 000000000..34447b1d7 --- /dev/null +++ b/hr_zk_attendance/models/zk_machine.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: cybrosys() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### +import pytz +import sys +import datetime +import logging +import binascii + +from . import zklib +from .zkconst import * +from struct import unpack +from odoo import api, fields, models +from odoo import _ +from odoo.exceptions import UserError, ValidationError +_logger = logging.getLogger(__name__) +try: + from zk import ZK, const +except ImportError: + _logger.error("Please Install pyzk library.") + +_logger = logging.getLogger(__name__) + + +class HrAttendance(models.Model): + _inherit = 'hr.attendance' + + device_id = fields.Char(string='Biometric Device ID') + + +class ZkMachine(models.Model): + _name = 'zk.machine' + + name = fields.Char(string='Machine IP', required=True) + port_no = fields.Integer(string='Port No', required=True) + address_id = fields.Many2one('res.partner', string='Working Address') + company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id.id) + + def device_connect(self, zk): + try: + conn = zk.connect() + return conn + except: + return False + + def clear_attendance(self): + for info in self: + try: + machine_ip = info.name + zk_port = info.port_no + timeout = 30 + try: + zk = ZK(machine_ip, port=zk_port, timeout=timeout, password=0, force_udp=False, ommit_ping=False) + except NameError: + raise UserError(_("Please install it with 'pip3 install pyzk'.")) + conn = self.device_connect(zk) + if conn: + conn.enable_device() + clear_data = zk.get_attendance() + if clear_data: + # conn.clear_attendance() + self._cr.execute("""delete from zk_machine_attendance""") + conn.disconnect() + raise UserError(_('Attendance Records Deleted.')) + else: + raise UserError(_('Unable to clear Attendance log. Are you sure attendance log is not empty.')) + else: + raise UserError( + _('Unable to connect to Attendance Device. Please use Test Connection button to verify.')) + except: + raise ValidationError( + 'Unable to clear Attendance log. Are you sure attendance device is connected & record is not empty.') + + def getSizeUser(self, zk): + """Checks a returned packet to see if it returned CMD_PREPARE_DATA, + indicating that data packets are to be sent + + Returns the amount of bytes that are going to be sent""" + command = unpack('HHHH', zk.data_recv[:8])[0] + if command == CMD_PREPARE_DATA: + size = unpack('I', zk.data_recv[8:12])[0] + print("size", size) + return size + else: + return False + + def zkgetuser(self, zk): + """Start a connection with the time clock""" + try: + users = zk.get_users() + print(users) + return users + except: + return False + + @api.model + def cron_download(self): + machines = self.env['zk.machine'].search([]) + for machine in machines : + machine.download_attendance() + + def download_attendance(self): + _logger.info("++++++++++++Cron Executed++++++++++++++++++++++") + zk_attendance = self.env['zk.machine.attendance'] + att_obj = self.env['hr.attendance'] + for info in self: + machine_ip = info.name + zk_port = info.port_no + timeout = 15 + try: + zk = ZK(machine_ip, port=zk_port, timeout=timeout, password=0, force_udp=False, ommit_ping=False) + except NameError: + raise UserError(_("Pyzk module not Found. Please install it with 'pip3 install pyzk'.")) + conn = self.device_connect(zk) + if conn: + # conn.disable_device() #Device Cannot be used during this time. + try: + user = conn.get_users() + except: + user = False + try: + attendance = conn.get_attendance() + except: + attendance = False + if attendance: + for each in attendance: + atten_time = each.timestamp + atten_time = datetime.strptime(atten_time.strftime('%Y-%m-%d %H:%M:%S'), '%Y-%m-%d %H:%M:%S') + local_tz = pytz.timezone( + self.env.user.partner_id.tz or 'GMT') + local_dt = local_tz.localize(atten_time, is_dst=None) + utc_dt = local_dt.astimezone(pytz.utc) + utc_dt = utc_dt.strftime("%Y-%m-%d %H:%M:%S") + atten_time = datetime.strptime( + utc_dt, "%Y-%m-%d %H:%M:%S") + atten_time = fields.Datetime.to_string(atten_time) + if user: + for uid in user: + if uid.user_id == each.user_id: + get_user_id = self.env['hr.employee'].search( + [('device_id', '=', each.user_id)]) + if get_user_id: + duplicate_atten_ids = zk_attendance.search( + [('device_id', '=', each.user_id), ('punching_time', '=', atten_time)]) + if duplicate_atten_ids: + continue + else: + zk_attendance.create({'employee_id': get_user_id.id, + 'device_id': each.user_id, + 'attendance_type': str(each.status), + 'punch_type': str(each.punch), + 'punching_time': atten_time, + 'address_id': info.address_id.id}) + att_var = att_obj.search([('employee_id', '=', get_user_id.id), + ('check_out', '=', False)]) + print('ddfcd', str(each.status)) + if each.punch == 0: #check-in + if not att_var: + att_obj.create({'employee_id': get_user_id.id, + 'check_in': atten_time}) + if each.punch == 1: #check-out + if len(att_var) == 1: + att_var.write({'check_out': atten_time}) + else: + att_var1 = att_obj.search([('employee_id', '=', get_user_id.id)]) + if att_var1: + att_var1[-1].write({'check_out': atten_time}) + + else: + print('ddfcd', str(each.status)) + print('user', uid.name) + employee = self.env['hr.employee'].create( + {'device_id': each.user_id, 'name': uid.name}) + zk_attendance.create({'employee_id': employee.id, + 'device_id': each.user_id, + 'attendance_type': str(each.status), + 'punch_type': str(each.punch), + 'punching_time': atten_time, + 'address_id': info.address_id.id}) + att_obj.create({'employee_id': employee.id, + 'check_in': atten_time}) + else: + pass + # zk.enableDevice() + conn.disconnect + return True + else: + raise UserError(_('Unable to get the attendance log, please try again later.')) + else: + raise UserError(_('Unable to connect, please check the parameters and network connections.')) diff --git a/hr_zk_attendance/models/zkattendance.py b/hr_zk_attendance/models/zkattendance.py new file mode 100644 index 000000000..3d34f1802 --- /dev/null +++ b/hr_zk_attendance/models/zkattendance.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: cybrosys() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### +import binascii +from struct import pack, unpack +from .zkconst import * + + +def getSizeAttendance(self): + """Checks a returned packet to see if it returned CMD_PREPARE_DATA, + indicating that data packets are to be sent + + Returns the amount of bytes that are going to be sent""" + command = unpack('HHHH', self.data_recv[:8])[0] + if command == CMD_PREPARE_DATA: + size = unpack('I', self.data_recv[8:12])[0] + return size + else: + return False + + +def reverseHex(hexstr): + tmp = '' + for i in reversed(range(int(len(hexstr)/2))): + tmp += hexstr[i*2:(i*2)+2] + + return tmp + +def zkgetattendance(self): + """Start a connection with the time clock""" + command = CMD_ATTLOG_RRQ + command_string = '' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + + if getSizeAttendance(self): + bytes = getSizeAttendance(self) + while bytes > 0: + data_recv, addr = self.zkclient.recvfrom(1032) + self.attendancedata.append(data_recv) + bytes -= 1024 + + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + data_recv = self.zkclient.recvfrom(8) + + attendance = [] + if len(self.attendancedata) > 0: + # The first 4 bytes don't seem to be related to the user + for x in range(len(self.attendancedata)): + if x > 0: + self.attendancedata[x] = self.attendancedata[x][8:] + + attendancedata = b''.join( self.attendancedata ) + + attendancedata = attendancedata[14:] + + while len(attendancedata) > 40: + + uid, state, timestamp, space = unpack( '24s1s4s11s', attendancedata.ljust(40)[:40] ) + + + # Clean up some messy characters from the user name + #uid = unicode(uid.strip('\x00|\x01\x10x'), errors='ignore') + uid = uid.split(b'\x00', 1)[0].decode('utf-8') + #print "%s, %s, %s" % (uid, state, decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) + + attendance.append( ( uid, int( binascii.hexlify(state), 16 ), decode_time( int( reverseHex( binascii.hexlify(timestamp).decode('utf-8')), 16 ) ) ) ) + + attendancedata = attendancedata[40:] + + return attendance + except: + return False + + +def zkclearattendance(self): + """Start a connection with the time clock""" + command = CMD_CLEAR_ATTLOG + command_string = '' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False diff --git a/hr_zk_attendance/models/zkconnect.py b/hr_zk_attendance/models/zkconnect.py new file mode 100644 index 000000000..4ee98595b --- /dev/null +++ b/hr_zk_attendance/models/zkconnect.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: cybrosys() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### +from struct import pack, unpack +from .zkconst import * + + +def zkconnect(self): + """Start a connection with the time clock""" + command = CMD_CONNECT + command_string = '' + chksum = 0 + session_id = 0 + reply_id = -1 + USHRT_MAX + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + + self.zkclient.sendto(buf, self.address) + + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + + return self.checkValid( self.data_recv ) + except: + return False + + +def zkdisconnect(self): + """Disconnect from the clock""" + command = CMD_EXIT + command_string = '' + chksum = 0 + session_id = self.session_id + + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + + self.zkclient.sendto(buf, self.address) + + self.data_recv, addr = self.zkclient.recvfrom(1024) + return self.checkValid( self.data_recv ) diff --git a/hr_zk_attendance/models/zkconst.py b/hr_zk_attendance/models/zkconst.py new file mode 100644 index 000000000..febfa2ab1 --- /dev/null +++ b/hr_zk_attendance/models/zkconst.py @@ -0,0 +1,71 @@ +from datetime import datetime, date + +USHRT_MAX = 65535 + + +CMD_CONNECT = 1000 +CMD_EXIT = 1001 +CMD_ENABLEDEVICE = 1002 +CMD_DISABLEDEVICE = 1003 + +CMD_ACK_OK = 2000 +CMD_ACK_ERROR = 2001 +CMD_ACK_DATA = 2002 + +CMD_PREPARE_DATA = 1500 +CMD_DATA = 1501 + +CMD_USERTEMP_RRQ = 9 +CMD_ATTLOG_RRQ = 13 +CMD_CLEAR_DATA = 14 +CMD_CLEAR_ATTLOG = 15 + +CMD_WRITE_LCD = 66 + +CMD_GET_TIME = 201 +CMD_SET_TIME = 202 + +CMD_VERSION = 1100 +CMD_DEVICE = 11 + +CMD_CLEAR_ADMIN = 20 +CMD_SET_USER = 8 + +LEVEL_USER = 0 +LEVEL_ADMIN = 14 + +def encode_time(t): + """Encode a timestamp send at the timeclock + + copied from zkemsdk.c - EncodeTime""" + d = ( (t.year % 100) * 12 * 31 + ((t.month - 1) * 31) + t.day - 1) *\ + (24 * 60 * 60) + (t.hour * 60 + t.minute) * 60 + t.second + + return d + + +def decode_time(t): + """Decode a timestamp retrieved from the timeclock + + copied from zkemsdk.c - DecodeTime""" + second = t % 60 + t = t / 60 + + minute = t % 60 + t = t / 60 + + hour = t % 24 + t = t / 24 + + day = t % 31+1 + t = t / 31 + + month = t % 12+1 + t = t / 12 + + year = t + 2000 + + d = datetime(int(year), int(month), int(day), int(hour), int(minute), int(second)) + + return d + diff --git a/hr_zk_attendance/models/zkdevice.py b/hr_zk_attendance/models/zkdevice.py new file mode 100644 index 000000000..cc8b4b468 --- /dev/null +++ b/hr_zk_attendance/models/zkdevice.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: cybrosys() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### +from struct import pack, unpack +from .zkconst import * + + +def zkdevicename(self): + """Start a connection with the time clock""" + command = CMD_DEVICE + command_string = '~DeviceName' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + + +def zkenabledevice(self): + """Start a connection with the time clock""" + command = CMD_ENABLEDEVICE + command_string = '' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + +def zkdisabledevice(self): + """Start a connection with the time clock""" + command = CMD_DISABLEDEVICE + command_string = '\x00\x00' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False diff --git a/hr_zk_attendance/models/zkextendfmt.py b/hr_zk_attendance/models/zkextendfmt.py new file mode 100644 index 000000000..0b2eaf4ef --- /dev/null +++ b/hr_zk_attendance/models/zkextendfmt.py @@ -0,0 +1,56 @@ +def zkextendfmt(self): + try: + test = self.exttrynumber + except: + self.exttrynumber = 1 + + data_seq=[ self.data_recv.encode("hex")[4:6], self.data_recv.encode("hex")[6:8] ] + #print data_seq + if self.exttrynumber == 1: + plus1 = 0 + plus2 = 0 + else: + plus1 = -1 + plus2 = +1 + + + desc = ": +"+hex( int('99', 16)+plus1 ).lstrip('0x')+", +"+hex(int('b1', 16)+plus2).lstrip("0x") + self.data_seq1 = hex( int( data_seq[0], 16 ) + int( '99', 16 ) + plus1 ).lstrip("0x") + self.data_seq2 = hex( int( data_seq[1], 16 ) + int( 'b1', 16 ) + plus2 ).lstrip("0x") + + if len(self.data_seq1) >= 3: + #self.data_seq2 = hex( int( self.data_seq2, 16 ) + int( self.data_seq1[:1], 16) ).lstrip("0x") + self.data_seq1 = self.data_seq1[-2:] + + if len(self.data_seq2) >= 3: + #self.data_seq1 = hex( int( self.data_seq1, 16 ) + int( self.data_seq2[:1], 16) ).lstrip("0x") + self.data_seq2 = self.data_seq2[-2:] + + + if len(self.data_seq1) <= 1: + self.data_seq1 = "0"+self.data_seq1 + + if len(self.data_seq2) <= 1: + self.data_seq2 = "0"+self.data_seq2 + + + counter = hex( self.counter ).lstrip("0x") + if len(counter): + counter = "0" + counter + #print self.data_seq1+" "+self.data_seq2+desc + data = "0b00"+self.data_seq1+self.data_seq2+self.id_com+counter+"007e457874656e64466d7400" + self.zkclient.sendto(data.decode("hex"), self.address) + #print data + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + except: + if self.exttrynumber == 1: + self.exttrynumber = 2 + tmp = zkextendfmt(self) + if len(tmp) < 1: + self.exttrynumber = 1 + + self.id_com = self.data_recv.encode("hex")[8:12] + self.counter = self.counter+1 + #print self.data_recv.encode("hex") + return self.data_recv[8:] diff --git a/hr_zk_attendance/models/zkextendoplog.py b/hr_zk_attendance/models/zkextendoplog.py new file mode 100644 index 000000000..19b5a7e06 --- /dev/null +++ b/hr_zk_attendance/models/zkextendoplog.py @@ -0,0 +1,61 @@ +def zkextendoplog(self, index=0): + try: + test = self.extlogtrynumber + except: + self.extlogtrynumber = 1 + + data_seq = [ self.data_recv.encode("hex")[4:6], self.data_recv.encode("hex")[6:8] ] + + if index==0: + self.data_seq1 = hex( int( data_seq[0], 16 ) + int( '104', 16 ) ).lstrip("0x") + self.data_seq2 = hex( int( data_seq[1], 16 ) + int( '19', 16 ) ).lstrip("0x") + desc = ": +104, +19" + header="0b00" + elif index==1: + self.data_seq1 = hex( abs( int( data_seq[0], 16 ) - int( '2c', 16 ) ) ).lstrip("0x") + self.data_seq2 = hex( abs( int( data_seq[1], 16 ) - int( '2', 16 ) ) ).lstrip("0x") + desc = ": -2c, -2" + header="d107" + elif index>=2: + self.data_seq1 = hex( abs( int( data_seq[0], 16 ) - int( '2c', 16 ) ) ).lstrip("0x") + self.data_seq2 = hex( abs( int( data_seq[1], 16 ) - int( '2', 16 ) ) ).lstrip("0x") + desc = ": -2c, -2" + header="ffff" + + + #print self.data_seq1+" "+self.data_seq2 + if len(self.data_seq1) >= 3: + self.data_seq2 = hex( int( self.data_seq2, 16 ) + int( self.data_seq1[:1], 16) ).lstrip("0x") + self.data_seq1 = self.data_seq1[-2:] + + if len(self.data_seq2) >= 3: + self.data_seq1 = hex( int( self.data_seq1, 16 ) + int( self.data_seq2[:1], 16) ).lstrip("0x") + self.data_seq2 = self.data_seq2[-2:] + + if len(self.data_seq1) <= 1: + self.data_seq1 = "0"+self.data_seq1 + + if len(self.data_seq2) <= 1: + self.data_seq2 = "0"+self.data_seq2 + + + counter = hex( self.counter ).lstrip("0x") + if len(counter): + counter = "0" + counter + + #print self.data_seq1+" "+self.data_seq2+desc + data = header+self.data_seq1+self.data_seq2+self.id_com+counter+"00457874656e644f504c6f6700" + self.zkclient.sendto(data.decode("hex"), self.address) + #print data + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + except: + bingung=1 + if self.extlogtrynumber == 1: + self.extlogtrynumber = 2 + zkextendoplog(self) + + self.id_com = self.data_recv.encode("hex")[8:12] + self.counter = self.counter+1 + #print self.data_recv.encode("hex") + return self.data_recv[8:] diff --git a/hr_zk_attendance/models/zkface.py b/hr_zk_attendance/models/zkface.py new file mode 100644 index 000000000..08e657816 --- /dev/null +++ b/hr_zk_attendance/models/zkface.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: cybrosys() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### +from struct import pack, unpack +from .zkconst import * + + +def zkfaceon(self): + """Start a connection with the time clock""" + command = CMD_DEVICE + command_string = 'FaceFunOn' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + diff --git a/hr_zk_attendance/models/zklib.py b/hr_zk_attendance/models/zklib.py new file mode 100644 index 000000000..3fb7201eb --- /dev/null +++ b/hr_zk_attendance/models/zklib.py @@ -0,0 +1,156 @@ +from socket import * +from .zkconnect import * +from .zkversion import * +from .zkos import * +from .zkextendfmt import * +from .zkextendoplog import * +from .zkplatform import * +from .zkworkcode import * +from .zkssr import * +from .zkpin import * +from .zkface import * +from .zkserialnumber import * +from .zkdevice import * +from .zkuser import * +from .zkattendance import * +from .zktime import * + +class ZKLib: + + def __init__(self, ip, port): + self.address = (ip, port) + self.zkclient = socket(AF_INET, SOCK_DGRAM) + self.zkclient.settimeout(3) + self.session_id = 0 + self.userdata = [] + self.attendancedata = [] + + + def createChkSum(self, p): + """This function calculates the chksum of the packet to be sent to the + time clock + + Copied from zkemsdk.c""" + l = len(p) + chksum = 0 + while l > 1: + chksum += unpack('H', pack('BB', p[0], p[1]))[0] + + p = p[2:] + if chksum > USHRT_MAX: + chksum -= USHRT_MAX + l -= 2 + + + if l: + chksum = chksum + p[-1] + + while chksum > USHRT_MAX: + chksum -= USHRT_MAX + + chksum = ~chksum + + while chksum < 0: + chksum += USHRT_MAX + + return pack('H', chksum) + + + def createHeader(self, command, chksum, session_id, reply_id, + command_string): + """This function puts a the parts that make up a packet together and + packs them into a byte string""" + buf = pack('HHHH', command, chksum, session_id, reply_id) + command_string.encode(encoding='utf_8', errors='strict') + + buf = unpack('8B'+'%sB' % len(command_string), buf) + + chksum = unpack('H', self.createChkSum(buf))[0] + #print unpack('H', self.createChkSum(buf)) + reply_id += 1 + if reply_id >= USHRT_MAX: + reply_id -= USHRT_MAX + + buf = pack('HHHH', command, chksum, session_id, reply_id) + return buf + command_string.encode(encoding='utf_8', errors='strict') + + + def checkValid(self, reply): + """Checks a returned packet to see if it returned CMD_ACK_OK, + indicating success""" + command = unpack('HHHH', reply[:8])[0] + if command == CMD_ACK_OK: + return True + else: + return False + + def connect(self): + return zkconnect(self) + + def disconnect(self): + return zkdisconnect(self) + + def version(self): + return zkversion(self) + + def osversion(self): + return zkos(self) + + def extendFormat(self): + return zkextendfmt(self) + + def extendOPLog(self, index=0): + return zkextendoplog(self, index) + + def platform(self): + return zkplatform(self) + + def fmVersion(self): + return zkplatformVersion(self) + + def workCode(self): + return zkworkcode(self) + + def ssr(self): + return zkssr(self) + + def pinWidth(self): + return zkpinwidth(self) + + def faceFunctionOn(self): + return zkfaceon(self) + + def serialNumber(self): + return zkserialnumber(self) + + def deviceName(self): + return zkdevicename(self) + + def disableDevice(self): + return zkdisabledevice(self) + + def enableDevice(self): + return zkenabledevice(self) + + def getUser(self): + return zkgetuser(self) + + def setUser(self, uid, userid, name, password, role): + return zksetuser(self, uid, userid, name, password, role) + + def clearUser(self): + return zkclearuser(self) + + def clearAdmin(self): + return zkclearadmin(self) + + def getAttendance(self): + return zkgetattendance(self) + + def clearAttendance(self): + return zkclearattendance(self) + + def setTime(self, t): + return zksettime(self, t) + + def getTime(self): + return zkgettime(self) diff --git a/hr_zk_attendance/models/zkos.py b/hr_zk_attendance/models/zkos.py new file mode 100644 index 000000000..b3f11dd74 --- /dev/null +++ b/hr_zk_attendance/models/zkos.py @@ -0,0 +1,23 @@ +from struct import pack, unpack +from .zkconst import * + + +def zkos(self): + """Start a connection with the time clock""" + command = CMD_DEVICE + command_string = '~OS' + chksum = 0 + session_id = self.session_id + + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False diff --git a/hr_zk_attendance/models/zkpin.py b/hr_zk_attendance/models/zkpin.py new file mode 100644 index 000000000..f25cd0b85 --- /dev/null +++ b/hr_zk_attendance/models/zkpin.py @@ -0,0 +1,23 @@ +from struct import pack, unpack +from .zkconst import * + + +def zkpinwidth(self): + """Start a connection with the time clock""" + command = CMD_DEVICE + command_string = '~PIN2Width' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + diff --git a/hr_zk_attendance/models/zkplatform.py b/hr_zk_attendance/models/zkplatform.py new file mode 100644 index 000000000..7068dc63c --- /dev/null +++ b/hr_zk_attendance/models/zkplatform.py @@ -0,0 +1,43 @@ +from struct import pack, unpack +from .zkconst import * + + +def zkplatform(self): + """Start a connection with the time clock""" + command = CMD_DEVICE + command_string = '~Platform' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + + +def zkplatformVersion(self): + """Start a connection with the time clock""" + command = CMD_DEVICE + command_string = '~ZKFPVersion' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + diff --git a/hr_zk_attendance/models/zkserialnumber.py b/hr_zk_attendance/models/zkserialnumber.py new file mode 100644 index 000000000..cd1098f98 --- /dev/null +++ b/hr_zk_attendance/models/zkserialnumber.py @@ -0,0 +1,23 @@ +from struct import pack, unpack +from .zkconst import * + + +def zkserialnumber(self): + """Start a connection with the time clock""" + command = CMD_DEVICE + command_string = '~SerialNumber' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + diff --git a/hr_zk_attendance/models/zkssr.py b/hr_zk_attendance/models/zkssr.py new file mode 100644 index 000000000..740a22119 --- /dev/null +++ b/hr_zk_attendance/models/zkssr.py @@ -0,0 +1,23 @@ +from struct import pack, unpack +from .zkconst import * + + +def zkssr(self): + """Start a connection with the time clock""" + command = CMD_DEVICE + command_string = '~SSR' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + diff --git a/hr_zk_attendance/models/zktime.py b/hr_zk_attendance/models/zktime.py new file mode 100644 index 000000000..e2d69b78d --- /dev/null +++ b/hr_zk_attendance/models/zktime.py @@ -0,0 +1,50 @@ +from struct import pack, unpack +from .zkconst import * + + +def reverseHex(hexstr): + tmp = '' + for i in reversed(range(len(hexstr)/2)): + tmp += hexstr[i*2:(i*2)+2] + + return tmp + + +def zksettime(self, t): + """Start a connection with the time clock""" + command = CMD_SET_TIME + command_string = pack('I',encode_time(t)) + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + + +def zkgettime(self): + """Start a connection with the time clock""" + command = CMD_GET_TIME + command_string = '' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return decode_time( int( reverseHex( self.data_recv[8:].encode("hex") ), 16 ) ) + except: + return False diff --git a/hr_zk_attendance/models/zkuser.py b/hr_zk_attendance/models/zkuser.py new file mode 100644 index 000000000..08756fd5d --- /dev/null +++ b/hr_zk_attendance/models/zkuser.py @@ -0,0 +1,140 @@ +from struct import pack, unpack +from .zkconst import * + + +def getSizeUser(self): + """Checks a returned packet to see if it returned CMD_PREPARE_DATA, + indicating that data packets are to be sent + + Returns the amount of bytes that are going to be sent""" + command = unpack('HHHH', self.data_recv[:8])[0] + if command == CMD_PREPARE_DATA: + size = unpack('I', self.data_recv[8:12])[0] + return size + else: + return False + + +def zksetuser(self, uid, userid, name, password, role): + """Start a connection with the time clock""" + command = CMD_SET_USER + command_string = pack('sxs8s28ss7sx8s16s', chr( uid ), chr(role), password, name, chr(1), '', userid, '' ) + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + + +def zkgetuser(self): + """Start a connection with the time clock""" + command = CMD_USERTEMP_RRQ + command_string = '\x05' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + + + if getSizeUser(self): + bytes = getSizeUser(self) + + while bytes > 0: + data_recv, addr = self.zkclient.recvfrom(1032) + self.userdata.append(data_recv) + bytes -= 1024 + + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + data_recv = self.zkclient.recvfrom(8) + + users = {} + if len(self.userdata) > 0: + # The first 4 bytes don't seem to be related to the user + for x in range(len(self.userdata)): + if x > 0: + self.userdata[x] = self.userdata[x][8:] + + userdata = ''.join( self.userdata ) + + userdata = userdata[11:] + + while len(userdata) > 72: + + uid, role, password, name, userid = unpack( '2s2s8s28sx31s', userdata.ljust(72)[:72] ) + + uid = int( uid.encode("hex"), 16) + # Clean up some messy characters from the user name + password = password.split('\x00', 1)[0] + password = unicode(password.strip('\x00|\x01\x10x'), errors='ignore') + + #uid = uid.split('\x00', 1)[0] + userid = unicode(userid.strip('\x00|\x01\x10x'), errors='ignore') + + name = name.split('\x00', 1)[0] + + if name.strip() == "": + name = uid + + users[uid] = (userid, name, int( role.encode("hex"), 16 ), password) + + #print("%d, %s, %s, %s, %s" % (uid, userid, name, int( role.encode("hex"), 16 ), password)) + userdata = userdata[72:] + + return users + except: + return False + + +def zkclearuser(self): + """Start a connection with the time clock""" + command = CMD_CLEAR_DATA + command_string = '' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + + +def zkclearadmin(self): + """Start a connection with the time clock""" + command = CMD_CLEAR_ADMIN + command_string = '' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False diff --git a/hr_zk_attendance/models/zkversion.py b/hr_zk_attendance/models/zkversion.py new file mode 100644 index 000000000..0ee6a1693 --- /dev/null +++ b/hr_zk_attendance/models/zkversion.py @@ -0,0 +1,23 @@ +from struct import pack, unpack +from .zkconst import * + + +def zkversion(self): + """Start a connection with the time clock""" + command = CMD_VERSION + command_string = '' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + diff --git a/hr_zk_attendance/models/zkworkcode.py b/hr_zk_attendance/models/zkworkcode.py new file mode 100644 index 000000000..10660e530 --- /dev/null +++ b/hr_zk_attendance/models/zkworkcode.py @@ -0,0 +1,23 @@ +from struct import pack, unpack +from .zkconst import * + + +def zkworkcode(self): + """Start a connection with the time clock""" + command = CMD_DEVICE + command_string = 'WorkCode' + chksum = 0 + session_id = self.session_id + reply_id = unpack('HHHH', self.data_recv[:8])[3] + + buf = self.createHeader(command, chksum, session_id, + reply_id, command_string) + self.zkclient.sendto(buf, self.address) + #print buf.encode("hex") + try: + self.data_recv, addr = self.zkclient.recvfrom(1024) + self.session_id = unpack('HHHH', self.data_recv[:8])[2] + return self.data_recv[8:] + except: + return False + diff --git a/hr_zk_attendance/security/ir.model.access.csv b/hr_zk_attendance/security/ir.model.access.csv new file mode 100644 index 000000000..438279985 --- /dev/null +++ b/hr_zk_attendance/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_hr_zk_machine_user,zk.machine.hr_biometric_machine,model_zk_machine,hr_attendance.group_hr_attendance_user,1,1,1,1 +access_hr_zk_machine_user1,zk.machine.hr_biometric_machine1,model_zk_machine_attendance,hr_attendance.group_hr_attendance_user,1,1,1,1 +access_hr_zk_machine_user2,zk.machine.hr_biometric_machine2,model_zk_report_daily_attendance,hr_attendance.group_hr_attendance_user,1,1,1,1 diff --git a/hr_zk_attendance/static/description/banner.gif b/hr_zk_attendance/static/description/banner.gif new file mode 100644 index 000000000..474c6e6b9 Binary files /dev/null and b/hr_zk_attendance/static/description/banner.gif differ diff --git a/hr_zk_attendance/static/description/cybro_logo.png b/hr_zk_attendance/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/hr_zk_attendance/static/description/cybro_logo.png differ diff --git a/hr_zk_attendance/static/description/icon.png b/hr_zk_attendance/static/description/icon.png new file mode 100644 index 000000000..e225e4da4 Binary files /dev/null and b/hr_zk_attendance/static/description/icon.png differ diff --git a/hr_zk_attendance/static/description/images/attendance log.png b/hr_zk_attendance/static/description/images/attendance log.png new file mode 100644 index 000000000..225495f52 Binary files /dev/null and b/hr_zk_attendance/static/description/images/attendance log.png differ diff --git a/hr_zk_attendance/static/description/images/banner.gif b/hr_zk_attendance/static/description/images/banner.gif new file mode 100644 index 000000000..c369e4496 Binary files /dev/null and b/hr_zk_attendance/static/description/images/banner.gif differ diff --git a/hr_zk_attendance/static/description/images/banner_lifeline_for_task.jpeg b/hr_zk_attendance/static/description/images/banner_lifeline_for_task.jpeg new file mode 100644 index 000000000..4a467ea22 Binary files /dev/null and b/hr_zk_attendance/static/description/images/banner_lifeline_for_task.jpeg differ diff --git a/hr_zk_attendance/static/description/images/banner_project_report_xls_pdf.png b/hr_zk_attendance/static/description/images/banner_project_report_xls_pdf.png new file mode 100644 index 000000000..3c430a7eb Binary files /dev/null and b/hr_zk_attendance/static/description/images/banner_project_report_xls_pdf.png differ diff --git a/hr_zk_attendance/static/description/images/banner_project_status_report.png b/hr_zk_attendance/static/description/images/banner_project_status_report.png new file mode 100644 index 000000000..d1b689710 Binary files /dev/null and b/hr_zk_attendance/static/description/images/banner_project_status_report.png differ diff --git a/hr_zk_attendance/static/description/images/banner_subtask.jpeg b/hr_zk_attendance/static/description/images/banner_subtask.jpeg new file mode 100644 index 000000000..f2b224110 Binary files /dev/null and b/hr_zk_attendance/static/description/images/banner_subtask.jpeg differ diff --git a/hr_zk_attendance/static/description/images/banner_task_deadline_reminder.jpeg b/hr_zk_attendance/static/description/images/banner_task_deadline_reminder.jpeg new file mode 100644 index 000000000..998679818 Binary files /dev/null and b/hr_zk_attendance/static/description/images/banner_task_deadline_reminder.jpeg differ diff --git a/hr_zk_attendance/static/description/images/banner_task_statusbar.jpeg b/hr_zk_attendance/static/description/images/banner_task_statusbar.jpeg new file mode 100644 index 000000000..2c57cbb7b Binary files /dev/null and b/hr_zk_attendance/static/description/images/banner_task_statusbar.jpeg differ diff --git a/hr_zk_attendance/static/description/images/biometric log.png b/hr_zk_attendance/static/description/images/biometric log.png new file mode 100644 index 000000000..e23997baa Binary files /dev/null and b/hr_zk_attendance/static/description/images/biometric log.png differ diff --git a/hr_zk_attendance/static/description/images/checked.png b/hr_zk_attendance/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/hr_zk_attendance/static/description/images/checked.png differ diff --git a/hr_zk_attendance/static/description/images/clear.png b/hr_zk_attendance/static/description/images/clear.png new file mode 100644 index 000000000..45ae8f4ff Binary files /dev/null and b/hr_zk_attendance/static/description/images/clear.png differ diff --git a/hr_zk_attendance/static/description/images/cybrosys.png b/hr_zk_attendance/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/hr_zk_attendance/static/description/images/cybrosys.png differ diff --git a/hr_zk_attendance/static/description/images/download.png b/hr_zk_attendance/static/description/images/download.png new file mode 100644 index 000000000..6a7e2972f Binary files /dev/null and b/hr_zk_attendance/static/description/images/download.png differ diff --git a/hr_zk_attendance/static/description/images/employee badge id.png b/hr_zk_attendance/static/description/images/employee badge id.png new file mode 100644 index 000000000..0b0c99943 Binary files /dev/null and b/hr_zk_attendance/static/description/images/employee badge id.png differ diff --git a/hr_zk_attendance/static/description/images/employee.png b/hr_zk_attendance/static/description/images/employee.png new file mode 100644 index 000000000..57c8dce60 Binary files /dev/null and b/hr_zk_attendance/static/description/images/employee.png differ diff --git a/hr_zk_attendance/static/description/images/icon.png b/hr_zk_attendance/static/description/images/icon.png new file mode 100644 index 000000000..e225e4da4 Binary files /dev/null and b/hr_zk_attendance/static/description/images/icon.png differ diff --git a/hr_zk_attendance/static/description/images/machine IP.png b/hr_zk_attendance/static/description/images/machine IP.png new file mode 100644 index 000000000..26adfdd77 Binary files /dev/null and b/hr_zk_attendance/static/description/images/machine IP.png differ diff --git a/hr_zk_attendance/static/description/index.html b/hr_zk_attendance/static/description/index.html new file mode 100644 index 000000000..c4c2a4fbb --- /dev/null +++ b/hr_zk_attendance/static/description/index.html @@ -0,0 +1,340 @@ +
cybrosys-logo
+
+
+
+

HR Biometric Device Integration

+

This Module Integrates Biometric Device With HR Attendance

+
+

Key Highlights

+
    +
  • Integrates biometric device(Face+Thumb) with HR attendance.
  • +
  • Option to keep the device attendance log in Odoo.
  • +
  • Option to clear the device attendance log from both device and Odoo.
  • +
  • Automating HR attendance.
  • +
  • Option to configure multiple devices.
  • +
  • This module will support with ZKteco model 'uFace 202', ZKteco model 'iFace990'
  • +
+
+
+
+ +
+
+
+
+ +
+
+ +

Overview

+
+

+ Automation is an implementation factor for a successful ERP. Using this module, HR attendance can be automated via integrating Thumb / Face detection device with Odoo. One can configure a user both from thumbing device or Odoo employee form.

+
+
+ +

HR Biometric Device Integration

+
+
    +

    + Integrates biometric device(Face+Thumb) with HR attendance. +

    + +

    + Option to keep the device attendance log in Odoo. +

    + +

    + Option to clear the device attendance log from both device and Odoo. +

    + +

    + Automating HR attendance. +

    + +

    + Option to configure multiple devices. +

    + +

    + This module will support with ZKteco model 'uFace 202', ZKteco model 'iFace990' +

    +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/hr_zk_attendance/views/zk_machine_attendance_view.xml b/hr_zk_attendance/views/zk_machine_attendance_view.xml new file mode 100644 index 000000000..8b5787174 --- /dev/null +++ b/hr_zk_attendance/views/zk_machine_attendance_view.xml @@ -0,0 +1,69 @@ + + + + + inherited_hr.attendance.tree + hr.attendance + + + + + + + + + + inherited_hr_attendance_view_filter + hr.attendance + + + + + + + + + + + + + + zk.report.daily.attendance.search + zk.report.daily.attendance + + + + + + + + + + + + + zk.report.daily.attendance.tree + zk.report.daily.attendance + + + + + + + + + + + + + + Attendance Analysis + zk.report.daily.attendance + tree + {'search_default_my_attendance':1} + + + + + diff --git a/hr_zk_attendance/views/zk_machine_view.xml b/hr_zk_attendance/views/zk_machine_view.xml new file mode 100644 index 000000000..80c5ee941 --- /dev/null +++ b/hr_zk_attendance/views/zk_machine_view.xml @@ -0,0 +1,68 @@ + + + + zk.machine.form + zk.machine + +
+
+
+ +
+
+ + + + + + + + + +
+
+
+
+ + + zk.machine.tree + zk.machine + + + + + + + + + + + + Attendances + zk.machine + tree,form + + + + hr.employee.form + hr.employee + + + + + + + + + + +
+ diff --git a/product_price_update_advanced/README.rst b/product_price_update_advanced/README.rst new file mode 100644 index 000000000..b6a6cbcc0 --- /dev/null +++ b/product_price_update_advanced/README.rst @@ -0,0 +1,46 @@ + +Advanced Product Price Update v14 +================================= + This module helps to update the cost price and sale price of any product in one single click + +Configuration +============= +* No additional configurations needed + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developers: Saritha Sahadevan V10, odoo@cybrosys.com + Niyas Raphy V11 @cybrosys, odoo@cybrosys.com + Vinaya S B V12 odoo@cybrosys.com + Mehjabin Farsana P V13 @cybrosys,odoo@cybrosys.com + Muhammed Nafih V14 odoo@cybrosys.com + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com +* Website : https://cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit `Our Website `__ + +Further information +=================== +HTML Description: ``__ + + + + diff --git a/product_price_update_advanced/__init__.py b/product_price_update_advanced/__init__.py new file mode 100644 index 000000000..d5883b592 --- /dev/null +++ b/product_price_update_advanced/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies ().# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### + +from . import models + + diff --git a/product_price_update_advanced/__manifest__.py b/product_price_update_advanced/__manifest__.py new file mode 100644 index 000000000..91889f365 --- /dev/null +++ b/product_price_update_advanced/__manifest__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2020-TODAY Cybrosys Technologies ().# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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': "Advanced Product Price Update", + 'version': '14.0.1.0.0', + 'summary': """User Can Easily Update Cost Price/Sale Price of Products""", + 'description': """This module updates price of any product on single click""", + 'author': "Cybrosys Techno Solutions", + 'company': 'Cybrosys Techno Solutions', + 'website': "https://www.Cybrosys.com", + 'category': 'Tools', + 'depends': ['base', 'sale'], + 'data': [ + 'views/product_price_view.xml', + 'security/ir.model.access.csv' + ], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/product_price_update_advanced/doc/RELEASE_NOTES.md b/product_price_update_advanced/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..c21be828e --- /dev/null +++ b/product_price_update_advanced/doc/RELEASE_NOTES.md @@ -0,0 +1,9 @@ +## Module + +#### 11.11.2020 +#### Version 14.0.1.0.0 +#### ADD +Initial Commit Advanced Product Price Update + + + diff --git a/product_price_update_advanced/models/__init__.py b/product_price_update_advanced/models/__init__.py new file mode 100644 index 000000000..3993ab5ca --- /dev/null +++ b/product_price_update_advanced/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import product_price diff --git a/product_price_update_advanced/models/product_price.py b/product_price_update_advanced/models/product_price.py new file mode 100644 index 000000000..596596e2c --- /dev/null +++ b/product_price_update_advanced/models/product_price.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Saritha Sahadevan @cybrosys(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from odoo import models, fields, api, _ + + +class ProductPrice(models.TransientModel): + _name = 'product.price' + + name = fields.Many2one('product.template', string="Product", required=True) + sale_price = fields.Integer(string="Sale Price", required=True) + cost_price = fields.Integer(string="Cost Price", required=True) + + def change_product_price(self): + prod_obj = self.env['product.template'].search([('id', '=', self.name.id)]) + prod_value = {'list_price': self.sale_price, 'standard_price': self.cost_price} + prod_obj.write(prod_value) + return { + 'name': _('Products'), + 'view_mode': 'form', + 'res_model': 'product.template', + 'type': 'ir.actions.act_window', + 'res_id': prod_obj.id, + 'context': self.env.context + } + + @api.onchange('name') + def get_price(self): + self.sale_price = self.name.list_price + self.cost_price = self.name.standard_price + + diff --git a/product_price_update_advanced/security/ir.model.access.csv b/product_price_update_advanced/security/ir.model.access.csv new file mode 100644 index 000000000..99fba203b --- /dev/null +++ b/product_price_update_advanced/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_product_price,access_product_price,model_product_price,,1,1,1,1 \ No newline at end of file diff --git a/product_price_update_advanced/static/description/banner.png b/product_price_update_advanced/static/description/banner.png new file mode 100644 index 000000000..55110e9d0 Binary files /dev/null and b/product_price_update_advanced/static/description/banner.png differ diff --git a/product_price_update_advanced/static/description/icon.png b/product_price_update_advanced/static/description/icon.png new file mode 100644 index 000000000..281d1c928 Binary files /dev/null and b/product_price_update_advanced/static/description/icon.png differ diff --git a/product_price_update_advanced/static/description/images/banner_lifeline_for_task.jpeg b/product_price_update_advanced/static/description/images/banner_lifeline_for_task.jpeg new file mode 100644 index 000000000..4a467ea22 Binary files /dev/null and b/product_price_update_advanced/static/description/images/banner_lifeline_for_task.jpeg differ diff --git a/product_price_update_advanced/static/description/images/banner_project_report_xls_pdf.png b/product_price_update_advanced/static/description/images/banner_project_report_xls_pdf.png new file mode 100644 index 000000000..3c430a7eb Binary files /dev/null and b/product_price_update_advanced/static/description/images/banner_project_report_xls_pdf.png differ diff --git a/product_price_update_advanced/static/description/images/banner_project_status_report.png b/product_price_update_advanced/static/description/images/banner_project_status_report.png new file mode 100644 index 000000000..d1b689710 Binary files /dev/null and b/product_price_update_advanced/static/description/images/banner_project_status_report.png differ diff --git a/product_price_update_advanced/static/description/images/banner_subtask.jpeg b/product_price_update_advanced/static/description/images/banner_subtask.jpeg new file mode 100644 index 000000000..f2b224110 Binary files /dev/null and b/product_price_update_advanced/static/description/images/banner_subtask.jpeg differ diff --git a/product_price_update_advanced/static/description/images/banner_task_deadline_reminder.jpeg b/product_price_update_advanced/static/description/images/banner_task_deadline_reminder.jpeg new file mode 100644 index 000000000..998679818 Binary files /dev/null and b/product_price_update_advanced/static/description/images/banner_task_deadline_reminder.jpeg differ diff --git a/product_price_update_advanced/static/description/images/banner_task_statusbar.jpeg b/product_price_update_advanced/static/description/images/banner_task_statusbar.jpeg new file mode 100644 index 000000000..2c57cbb7b Binary files /dev/null and b/product_price_update_advanced/static/description/images/banner_task_statusbar.jpeg differ diff --git a/product_price_update_advanced/static/description/images/checked.png b/product_price_update_advanced/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/product_price_update_advanced/static/description/images/checked.png differ diff --git a/product_price_update_advanced/static/description/images/cybrosys.png b/product_price_update_advanced/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/product_price_update_advanced/static/description/images/cybrosys.png differ diff --git a/product_price_update_advanced/static/description/images/price update.png b/product_price_update_advanced/static/description/images/price update.png new file mode 100644 index 000000000..95bbd96d1 Binary files /dev/null and b/product_price_update_advanced/static/description/images/price update.png differ diff --git a/product_price_update_advanced/static/description/images/price.png b/product_price_update_advanced/static/description/images/price.png new file mode 100644 index 000000000..eb3f1a188 Binary files /dev/null and b/product_price_update_advanced/static/description/images/price.png differ diff --git a/product_price_update_advanced/static/description/index.html b/product_price_update_advanced/static/description/index.html new file mode 100644 index 000000000..bece26241 --- /dev/null +++ b/product_price_update_advanced/static/description/index.html @@ -0,0 +1,299 @@ +
cybrosys-logo
+
+
+
+

Advanced Product Price Update

+

User Can Easily Update Cost Price/Sale Price of Products

+
+

Key Highlights

+
    +
  • Updates sale price
  • +
  • Updates cost price
  • +
+
+
+
+
+
+
+
+
+ +
+
+ +

Overview

+
+

+ Currently in Odoo, we need to switch over to each product form to update the price of product. This module helps to update the cost price and sale price of any product in one single click. * Create a wizard button in the menu Sales > 'Update Product'. * After filling wizard form and clicking on 'Update', it will change the selected price field of products that were selected in the wizard. +

+
+ + + + + +
+ + +

Configuration

+
+
    +
  • + No additional configuration required. +
  • +
+
+
+ +

Advanced Product Price Update

+
+
    +
  • + Updates sale price +
  • +
  • + Updates cost price +
  • +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/product_price_update_advanced/views/product_price_view.xml b/product_price_update_advanced/views/product_price_view.xml new file mode 100644 index 000000000..a20412af3 --- /dev/null +++ b/product_price_update_advanced/views/product_price_view.xml @@ -0,0 +1,40 @@ + + + + + + Update Product Price + product.price + +
+ + + + + + + + +
+
+
+
+
+ + + Update Product Price + product.price + ir.actions.act_window + form + + new + + + + +
+
\ No newline at end of file diff --git a/product_visibility_website/README.rst b/product_visibility_website/README.rst new file mode 100755 index 000000000..382d80f06 --- /dev/null +++ b/product_visibility_website/README.rst @@ -0,0 +1,35 @@ +============================ +Website Product Visibility +============================ +This module helps you to make visible only the filtered products and +product categories for a logged in and logged out users/visitors.Also, +it enables the user to search products and product categories only from +those available products and categories. . +Tech +==== +* [Python] - Models +* [XML] - Odoo views + +Installation +============ +- www.odoo.com/documentation/13.0/setup/install.html +- Install our custom addon + +Developer: Shijin V @Cybrosys + V14: Muhammed Nafih @Cybrosys + +Bug Tracker +=========== +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Credits +======= +* Cybrosys Techno Solutions + +Maintainer +---------- + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com. + diff --git a/product_visibility_website/__init__.py b/product_visibility_website/__init__.py new file mode 100644 index 000000000..ec25d99be --- /dev/null +++ b/product_visibility_website/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### + +from . import controllers +from . import models diff --git a/product_visibility_website/__manifest__.py b/product_visibility_website/__manifest__.py new file mode 100644 index 000000000..47deff655 --- /dev/null +++ b/product_visibility_website/__manifest__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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': 'Website Product Visibility', + 'summary': 'Website Product visibility for Users', + 'version': '14.0.1.0.0', + 'description': """Website Product visibility for Users""", + 'author': 'Cybrosys Techno Solution', + 'maintainer': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'category': 'Website', + 'depends': ['contacts', 'website_sale'], + 'data': [ + 'views/website_product_visibility.xml', + ], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/product_visibility_website/controllers/__init__.py b/product_visibility_website/controllers/__init__.py new file mode 100644 index 000000000..6b634292c --- /dev/null +++ b/product_visibility_website/controllers/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### + +from . import main diff --git a/product_visibility_website/controllers/main.py b/product_visibility_website/controllers/main.py new file mode 100644 index 000000000..a41a5535f --- /dev/null +++ b/product_visibility_website/controllers/main.py @@ -0,0 +1,332 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### + +from werkzeug.exceptions import NotFound +from odoo.addons.http_routing.models.ir_http import slug +from addons.website.controllers.main import QueryURL +from addons.website_sale.controllers.main import TableCompute +from odoo import http +from ast import literal_eval +from odoo.http import request +from odoo.addons.website.models.ir_http import sitemap_qs2dom +from odoo.addons.website_sale.controllers.main import WebsiteSale + +from odoo.osv import expression + + + +class ProductVisibilityCon(WebsiteSale): + + def sitemap_shop(env, rule, qs): + if not qs or qs.lower() in '/shop': + yield {'loc': '/shop'} + category = env['product.public.category'] + dom = sitemap_qs2dom(qs, '/shop/category', category._rec_name) + dom += env['website'].get_current_website().website_domain() + for cat in category.search(dom): + loc = '/shop/category/%s' % slug(cat) + if not qs or qs.lower() in loc: + yield {'loc': loc} + + def reset_domain(self, search, categories, available_products, attrib_values, search_in_description=True): + ''' + Function returns a domain consist of filter conditions + :param search: search variable + :param categories: list of category available + :param available_products: list of available product ids from product.template + :param attrib_values:product attiribute values + :param search_in_description: boolean filed showing there is search variable exist or not''' + + domains = [request.website.sale_product_domain()] + if search: + for srch in search.split(" "): + subdomains = [ + [('name', 'ilike', srch)], + [('product_variant_ids.default_code', 'ilike', srch)] + ] + if search_in_description: + subdomains.append([('description', 'ilike', srch)]) + subdomains.append([('description_sale', 'ilike', srch)]) + domains.append(expression.OR(subdomains)) + if available_products: + domains.append([('id', 'in', available_products.ids)]) + if categories: + domains.append([('public_categ_ids', 'child_of', categories.ids)]) + if attrib_values: + print("hello world....") + # attrib = None + # ids = [] + # print("hello...", ids) + # for value in attrib_values: + # if not attrib: + # attrib = value[0] + # ids.append(value[1]) + # elif value[0] == attrib: + # ids.append(value[1]) + # else: + # domains.append([('attribute_line_ids.value_ids', 'in', ids)]) + # attrib = value[0] + # ids = [value[1]] + # if attrib: + # domains.append([('attribute_line_ids.value_ids', 'in', ids)]) + + return expression.AND(domains) + + @http.route([ + '''/shop''', + '''/shop/page/''', + '''/shop/category/''', + '''/shop/category//page/''' + ], type='http', auth="public", website=True, sitemap=sitemap_shop) + def shop(self, page=0, category=None, search='', ppg=False, **post): + ''''Override shop function.''' + available_categ = available_products = '' + user = request.env['res.users'].sudo().search([('id', '=', request.env.user.id)]) + if not user: + mode = request.env['ir.config_parameter'].sudo().get_param('filter_mode') + products = literal_eval(request.env['ir.config_parameter'].sudo().get_param('website_product_visibility.available_product_ids', 'False')) + if mode == 'product_only': + available_products = request.env['product.template'].search([('id', 'in', products)]) + cat = literal_eval(request.env['ir.config_parameter'].sudo().get_param('website_product_visibility.available_cat_ids', 'False')) + available_categ = request.env['product.public.category'].search([('id', 'in', cat)]) + else: + partner = request.env['res.partner'].sudo().search([('id', '=', user.partner_id.id)]) + mode = partner.filter_mode + if mode == 'product_only': + available_products = self.availavle_products() + available_categ = partner.website_available_cat_ids + + Category_avail = [] + Category = request.env['product.public.category'] + + for ids in available_categ: + if not ids.parent_id.id in available_categ.ids: + Category_avail.append(ids.id) + categ = request.env['product.public.category'].search([('id', 'in', Category_avail)]) + if mode == 'product_only': + categ = Category.search([('parent_id', '=', False), ('product_tmpl_ids', 'in', available_products.ids)]) + + # supering shop*** + + if not available_categ and not available_products: + return super(ProductVisibilityCon, self).shop(page, category, search, ppg, **post) + add_qty = int(post.get('add_qty', 1)) + + if category: + category = Category.search([('id', '=', int(category))], limit=1) + if not category or not category.can_access_from_current_website(): + raise NotFound() + else: + category = Category + + if ppg: + try: + ppg = int(ppg) + post['ppg'] = ppg + except ValueError: + ppg = False + if not ppg: + ppg = request.env['website'].get_current_website().shop_ppg or 20 + ppr = request.env['website'].get_current_website().shop_ppr or 4 + attrib_list = request.httprequest.args.getlist('attrib') + attrib_values = [[int(x) for x in v.split("-")] for v in attrib_list if v] + attributes_ids = {v[0] for v in attrib_values} + attrib_set = {v[1] for v in attrib_values} + domain = self._get_search_domain(search, category, attrib_values) + Product = request.env['product.template'].with_context(bin_size=True) + if available_products: + domain_pro = self.reset_domain(search, category, available_products, attrib_values) + Product = Product.search(domain_pro) + keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_list, + order=post.get('order')) + pricelist_context, pricelist = self._get_pricelist_context() + request.context = dict(request.context, pricelist=pricelist.id, partner=request.env.user.partner_id) + url = "/shop" + if search: + post["search"] = search + if attrib_list: + post['attrib'] = attrib_list + if not category: + domain = self.reset_domain(search, available_categ, available_products, attrib_values) + search_product = Product.search(domain) + website_domain = request.website.website_domain() + categs_domain = [('parent_id', '=', False), ('product_tmpl_ids', 'in', search_product.ids)] + website_domain + if search: + search_categories = Category.search( + [('product_tmpl_ids', 'in', search_product.ids)] + website_domain).parents_and_self + categs_domain.append(('id', 'in', search_categories.ids)) + else: + search_categories = available_categ + if category: + url = "/shop/category/%s" % slug(category) + product_count = len(search_product) + pager = request.website.pager(url=url, total=product_count, page=page, step=ppg, scope=7, url_args=post) + products = Product.search(domain, limit=ppg, offset=pager['offset'], order=self._get_search_order(post)) + if not category: + if available_products: + products = Product.search(domain_pro, limit=ppg, offset=pager['offset'], + order=self._get_search_order(post)) + else: + products = Product.search(domain, limit=ppg, offset=pager['offset'], + order=self._get_search_order(post)) + else: + if available_products: + products = Product.search(domain_pro, limit=ppg, offset=pager['offset'], + order=self._get_search_order(post)) + else: + products = Product.search(domain, limit=ppg, offset=pager['offset'], + order=self._get_search_order(post)) + ProductAttribute = request.env['product.attribute'] + if products: + # get all products without limit + attributes = ProductAttribute.search([('product_tmpl_ids', 'in', search_product.ids)]) + else: + attributes = ProductAttribute.browse(attributes_ids) + + layout_mode = request.session.get('website_sale_shop_layout_mode') + if not layout_mode: + if request.website.viewref('website_sale.products_list_view').active: + layout_mode = 'list' + else: + layout_mode = 'grid' + values = { + 'search': search, + 'category': category, + 'attrib_values': attrib_values, + 'attrib_set': attrib_set, + 'pager': pager, + 'pricelist': pricelist, + 'add_qty': add_qty, + 'products': products, + 'search_count': product_count, # common for all searchbox + 'bins': TableCompute().process(products, ppg, ppr), + 'ppg': ppg, + 'ppr': ppr, + 'categories': categ, + 'attributes': attributes, + 'keep': keep, + 'search_categories_ids': categ.ids, + 'layout_mode': layout_mode, + } + + if category: + values['main_object'] = category + return request.render("website_sale.products", values) + + def availavle_products(self): + ''''Returns the available product (product.template) ids''' + user = request.env['res.users'].sudo().search([('id', '=', request.env.user.id)]) + partner = request.env['res.partner'].sudo().search([('id', '=', user.partner_id.id)]) + return partner.website_available_product_ids + + # -------------------------------------------------------------------------- + # Products Search Bar + # -------------------------------------------------------------------------- + + @http.route('/shop/products/autocomplete', type='json', auth='public', website=True) + def products_autocomplete(self, term, options={}, **kwargs): + """ + Returns list of products according to the term and product options + + Params: + term (str): search term written by the user + options (dict) + - 'limit' (int), default to 5: number of products to consider + - 'display_description' (bool), default to True + - 'display_price' (bool), default to True + - 'order' (str) + - 'max_nb_chars' (int): max number of characters for the + description if returned + + Returns: + dict (or False if no result) + - 'products' (list): products (only their needed field values) + note: the prices will be strings properly formatted and + already containing the currency + - 'products_count' (int): the number of products in the database + that matched the search query + """ + + user = request.env['res.users'].sudo().search([('id', '=', request.env.user.id)]) + available_categ = available_products = '' + if not user: + mode = request.env['ir.config_parameter'].sudo().get_param('filter_mode') + products = literal_eval( + request.env['ir.config_parameter'].sudo().get_param('website_product_visibility.available_product_ids', + 'False')) + if mode == 'product_only': + available_products = request.env['product.template'].search([('id', 'in', products)]) + cat = literal_eval( + request.env['ir.config_parameter'].sudo().get_param('website_product_visibility.available_cat_ids', + 'False')) + available_categ = request.env['product.public.category'].search([('id', 'in', cat)]) + else: + partner = request.env['res.partner'].sudo().search([('id', '=', user.partner_id.id)]) + mode = partner.filter_mode + if mode != 'categ_only': + available_products = self.availavle_products() + available_categ = partner.website_available_cat_ids + ProductTemplate = request.env['product.template'] + display_description = options.get('display_description', True) + display_price = options.get('display_price', True) + order = self._get_search_order(options) + max_nb_chars = options.get('max_nb_chars', 999) + category = options.get('category') + attrib_values = options.get('attrib_values') + + if not available_products and not available_categ: + domain = self._get_search_domain(term, category, attrib_values, display_description) + else: + domain = self.reset_domain(term,available_categ, available_products, attrib_values,display_description) + products = ProductTemplate.search( + domain, + limit=min(20, options.get('limit', 5)), + order=order + ) + fields = ['id', 'name', 'website_url'] + if display_description: + fields.append('description_sale') + + res = { + 'products': products.read(fields), + 'products_count': ProductTemplate.search_count(domain), + } + + if display_description: + for res_product in res['products']: + desc = res_product['description_sale'] + if desc and len(desc) > max_nb_chars: + res_product['description_sale'] = "%s..." % desc[:(max_nb_chars - 3)] + + if display_price: + FieldMonetary = request.env['ir.qweb.field.monetary'] + monetary_options = { + 'display_currency': request.website.get_current_pricelist().currency_id, + } + for res_product, product in zip(res['products'], products): + combination_info = product._get_combination_info(only_template=True) + res_product.update(combination_info) + res_product['list_price'] = FieldMonetary.value_to_html(res_product['list_price'], monetary_options) + res_product['price'] = FieldMonetary.value_to_html(res_product['price'], monetary_options) + + return res diff --git a/product_visibility_website/doc/RELEASE_NOTES.md b/product_visibility_website/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..a31eeaf5c --- /dev/null +++ b/product_visibility_website/doc/RELEASE_NOTES.md @@ -0,0 +1,9 @@ +## Module + +#### 31.03.2020 +#### Version 14.0.1.0.0 +##### ADD + + + + diff --git a/product_visibility_website/models/__init__.py b/product_visibility_website/models/__init__.py new file mode 100644 index 000000000..ad66c1036 --- /dev/null +++ b/product_visibility_website/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### + +from . import website_product_visibility diff --git a/product_visibility_website/models/website_product_visibility.py b/product_visibility_website/models/website_product_visibility.py new file mode 100644 index 000000000..3d4d3c3e2 --- /dev/null +++ b/product_visibility_website/models/website_product_visibility.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### + +from odoo import fields, models, api +from ast import literal_eval + + +class ProductVisibility(models.Model): + _inherit = 'res.partner' + + filter_mode = fields.Selection([('null', 'No Filter'), ('product_only', 'Product Wise'), + ('categ_only', 'Category Wise')], string='Filter Mode', default='null') + website_available_product_ids = fields.Many2many('product.template', string='Available Product', + domain="[('is_published', '=', True)]", + help='The website will only display products which are within one ' + 'of the selected category trees. If no category is specified,' + ' all available products will be shown') + website_available_cat_ids = fields.Many2many('product.public.category', string='Available Product Categories', + help='The website will only display products which are selected.' + ' If no product is specified,' + ' all available products will be shown') + + @api.onchange("filter_mode") + def onchange_filter_mod(self): + if self.filter_mode == 'null': + self.website_available_cat_ids = None + self.website_available_product_ids = None + +class WebsiteGuestVisibility(models.TransientModel): + _inherit = 'res.config.settings' + + product_visibility_guest_user = fields.Boolean(string="Product visibility Guest User") + filter_mode = fields.Selection([('product_only', 'Product Wise'), + ('categ_only', 'Category Wise')], string='Filter Mode', default='product_only') + + available_product_ids = fields.Many2many('product.template', string='Available Product', + domain="[('is_published', '=', True)]", + help='The website will only display products which are within one ' + 'of the selected category trees. If no category is specified,' + ' all available products will be shown') + available_cat_ids = fields.Many2many('product.public.category', string='Available Product Categories', + help='The website will only display products which are selected.' + ' If no product is specified,' + ' all available products will be shown') + + @api.model + def set_values(self): + res = super(WebsiteGuestVisibility, self).set_values() + self.env['ir.config_parameter'].sudo().set_param('product_visibility_guest_user', + self.product_visibility_guest_user) + self.env['ir.config_parameter'].sudo().set_param('filter_mode', self.filter_mode) + if not self.product_visibility_guest_user: + self.available_cat_ids = None + self.available_product_ids = None + self.env['ir.config_parameter'].sudo().set_param('filter_mode','product_only') + if self.filter_mode == 'product_only': + self.available_cat_ids = None + elif self.filter_mode == 'categ_only': + self.available_product_ids = None + + self.env['ir.config_parameter'].sudo().set_param('website_product_visibility.available_product_ids', + self.available_product_ids.ids) + self.env['ir.config_parameter'].sudo().set_param('website_product_visibility.available_cat_ids', + self.available_cat_ids.ids) + return res + + @api.model + def get_values(self): + res = super(WebsiteGuestVisibility, self).get_values() + product_ids = literal_eval(self.env['ir.config_parameter'].sudo().get_param('website_product_visibility.available_product_ids', 'False')) + cat_ids = literal_eval(self.env['ir.config_parameter'].sudo().get_param('website_product_visibility.available_cat_ids', 'False')) + mod = self.env['ir.config_parameter'].sudo().get_param('filter_mode') + res.update( + product_visibility_guest_user=self.env['ir.config_parameter'].sudo().get_param( + 'product_visibility_guest_user'), + filter_mode=mod if mod else 'product_only', + available_product_ids=[(6, 0, product_ids)], + available_cat_ids=[(6, 0, cat_ids)], + ) + return res diff --git a/product_visibility_website/static/description/banner.png b/product_visibility_website/static/description/banner.png new file mode 100644 index 000000000..bbc4b6b92 Binary files /dev/null and b/product_visibility_website/static/description/banner.png differ diff --git a/product_visibility_website/static/description/icon.png b/product_visibility_website/static/description/icon.png new file mode 100644 index 000000000..da802093f Binary files /dev/null and b/product_visibility_website/static/description/icon.png differ diff --git a/product_visibility_website/static/description/images/checked.png b/product_visibility_website/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/product_visibility_website/static/description/images/checked.png differ diff --git a/product_visibility_website/static/description/images/cybrosys.png b/product_visibility_website/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/product_visibility_website/static/description/images/cybrosys.png differ diff --git a/product_visibility_website/static/description/images/odoo-powr-countdown-timer-12.0.1.0.zip b/product_visibility_website/static/description/images/odoo-powr-countdown-timer-12.0.1.0.zip new file mode 100644 index 000000000..54b4beb1f Binary files /dev/null and b/product_visibility_website/static/description/images/odoo-powr-countdown-timer-12.0.1.0.zip differ diff --git a/product_visibility_website/static/description/images/paytm_payment_gateway.gif b/product_visibility_website/static/description/images/paytm_payment_gateway.gif new file mode 100644 index 000000000..d18f662d3 Binary files /dev/null and b/product_visibility_website/static/description/images/paytm_payment_gateway.gif differ diff --git a/product_visibility_website/static/description/images/product_brand_ecommerce.png b/product_visibility_website/static/description/images/product_brand_ecommerce.png new file mode 100644 index 000000000..4a3246e78 Binary files /dev/null and b/product_visibility_website/static/description/images/product_brand_ecommerce.png differ diff --git a/product_visibility_website/static/description/images/scrn1.png b/product_visibility_website/static/description/images/scrn1.png new file mode 100644 index 000000000..462407dbd Binary files /dev/null and b/product_visibility_website/static/description/images/scrn1.png differ diff --git a/product_visibility_website/static/description/images/scrn10.png b/product_visibility_website/static/description/images/scrn10.png new file mode 100644 index 000000000..5f67bf6a5 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn10.png differ diff --git a/product_visibility_website/static/description/images/scrn2.png b/product_visibility_website/static/description/images/scrn2.png new file mode 100644 index 000000000..54628a8dd Binary files /dev/null and b/product_visibility_website/static/description/images/scrn2.png differ diff --git a/product_visibility_website/static/description/images/scrn3.png b/product_visibility_website/static/description/images/scrn3.png new file mode 100644 index 000000000..626c16571 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn3.png differ diff --git a/product_visibility_website/static/description/images/scrn4.png b/product_visibility_website/static/description/images/scrn4.png new file mode 100644 index 000000000..01bf06e39 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn4.png differ diff --git a/product_visibility_website/static/description/images/scrn5.png b/product_visibility_website/static/description/images/scrn5.png new file mode 100644 index 000000000..85befd215 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn5.png differ diff --git a/product_visibility_website/static/description/images/scrn6.png b/product_visibility_website/static/description/images/scrn6.png new file mode 100644 index 000000000..263c5679a Binary files /dev/null and b/product_visibility_website/static/description/images/scrn6.png differ diff --git a/product_visibility_website/static/description/images/scrn7.png b/product_visibility_website/static/description/images/scrn7.png new file mode 100644 index 000000000..fc9ee5ed3 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn7.png differ diff --git a/product_visibility_website/static/description/images/scrn8.png b/product_visibility_website/static/description/images/scrn8.png new file mode 100644 index 000000000..e78a07031 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn8.png differ diff --git a/product_visibility_website/static/description/images/scrn9.png b/product_visibility_website/static/description/images/scrn9.png new file mode 100644 index 000000000..21744894f Binary files /dev/null and b/product_visibility_website/static/description/images/scrn9.png differ diff --git a/product_visibility_website/static/description/images/website_featured_products.jpeg b/product_visibility_website/static/description/images/website_featured_products.jpeg new file mode 100644 index 000000000..9542b3f7a Binary files /dev/null and b/product_visibility_website/static/description/images/website_featured_products.jpeg differ diff --git a/product_visibility_website/static/description/images/website_repeat_sale.jpeg b/product_visibility_website/static/description/images/website_repeat_sale.jpeg new file mode 100644 index 000000000..dc8e987fb Binary files /dev/null and b/product_visibility_website/static/description/images/website_repeat_sale.jpeg differ diff --git a/product_visibility_website/static/description/images/website_sale_advanced_search.png b/product_visibility_website/static/description/images/website_sale_advanced_search.png new file mode 100644 index 000000000..691f06847 Binary files /dev/null and b/product_visibility_website/static/description/images/website_sale_advanced_search.png differ diff --git a/product_visibility_website/static/description/images/website_sale_product_quick_view.jpeg b/product_visibility_website/static/description/images/website_sale_product_quick_view.jpeg new file mode 100644 index 000000000..6fa520659 Binary files /dev/null and b/product_visibility_website/static/description/images/website_sale_product_quick_view.jpeg differ diff --git a/product_visibility_website/static/description/index.html b/product_visibility_website/static/description/index.html new file mode 100644 index 000000000..b8f055f3a --- /dev/null +++ b/product_visibility_website/static/description/index.html @@ -0,0 +1,351 @@ +
cybrosys-logo
+
+
+
+

Website Product Visibility

+

Website Product visibility for logged in and logged out users/Visitors.

+
+

Key Highlights

+
    +
  • Filter product and product categories according to the logged user.
  • +
  • Filter product and product categories according to the public users/visitors.
  • +
  • User can only search product and category among from the available product/category.
  • +
+
+ +
+
+
+
+
+ +
+
+ +

Overview

+
+

+ This module helps you to make visible only the filtered products and product categories for a logged in and logged out users/visitors.Also, it enables the user to search products and product categories only from those available products and categories. +

+
+
+ +

Website Product Visibility

+
+
    +
  • + Filter product and product categories according to the logged user. +
  • +
  • + Filter product and product categories according to the public users/visitors. +
  • +
  • + User can only search product and category among from the available product/category. +
  • +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/product_visibility_website/views/website_product_visibility.xml b/product_visibility_website/views/website_product_visibility.xml new file mode 100644 index 000000000..e12b3235d --- /dev/null +++ b/product_visibility_website/views/website_product_visibility.xml @@ -0,0 +1,66 @@ + + + + + base.view.partner.form.inherit + res.partner + + + + + + + + + + + + + + + + + + + + + website.config.view.inherit + res.config.settings + + + +
+

Product Visibility

+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/product_volume/README.rst b/product_volume/README.rst new file mode 100755 index 000000000..7918853cd --- /dev/null +++ b/product_volume/README.rst @@ -0,0 +1,35 @@ +Product Volume v14 +================== +This module will helps you to give the length, breadth and height of the product + +Features +======== + +* Provision to enter the length, breadth and height of the product. +* Automaticaly calculates the volume + +Tech +==== +* [Python] - Models +* [XML] - Odoo views + +Installation +============ +- www.odoo.com/documentation/13.0/setup/install.html +- Install our custom addon + +Bug Tracker +=========== +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + + +Developer: Tintuk Tomin @ cybrosys, odoo@cybrosys.com + Kripal K V13 @ cybrosys, odoo@cybrosys.com + Muhammed Nafih V14 @ cybrosys, odoo@cybrosys.com + +Maintainer +---------- + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com. diff --git a/product_volume/__init__.py b/product_volume/__init__.py new file mode 100644 index 000000000..698385290 --- /dev/null +++ b/product_volume/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Tintuk Tomin @cybrosys(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from . import models diff --git a/product_volume/__manifest__.py b/product_volume/__manifest__.py new file mode 100755 index 000000000..3f58a83f9 --- /dev/null +++ b/product_volume/__manifest__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Tintuk Tomin @cybrosys(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# + +{ + 'name': 'Product Volume Calculation', + 'version': '14.0.1.0.0', + 'summary': """This module will helps you to give dimensions of the product.""", + 'description': "Module helps you to manage the length, breadth and height of the product and calculates its volume accordingily.", + 'category': "Inventory", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['base', 'stock'], + 'data': [ + 'views/volume_view.xml' + ], + 'demo': [], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'installable': True, + 'application': True, +} diff --git a/product_volume/doc/RELEASE_NOTES.md b/product_volume/doc/RELEASE_NOTES.md new file mode 100755 index 000000000..85822946c --- /dev/null +++ b/product_volume/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 03.12.2019 +#### Version 14.0.1.0.0 +#### ADD +Initial Commit Product Volume Calculation diff --git a/product_volume/models/__init__.py b/product_volume/models/__init__.py new file mode 100644 index 000000000..ef2f5750c --- /dev/null +++ b/product_volume/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Tintuk Tomin @cybrosys(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from . import volume diff --git a/product_volume/models/volume.py b/product_volume/models/volume.py new file mode 100644 index 000000000..58d9b5524 --- /dev/null +++ b/product_volume/models/volume.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Tintuk Tomin @cybrosys(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from odoo import api, models, fields + + +class ProductDimensionsVolume(models.Model): + _inherit = 'product.template' + + length = fields.Char(string="Length") + breadth = fields.Char(string="Breadth") + height = fields.Char(string="Height") + + @api.onchange('length', 'breadth', 'height') + def onchange_l_b_h(self): + self.volume = float(self.length if self.length else 0) * float(self.breadth if self.breadth else 0) * float( + self.height if self.height else 0) diff --git a/product_volume/static/description/banner.png b/product_volume/static/description/banner.png new file mode 100644 index 000000000..80ad7b39d Binary files /dev/null and b/product_volume/static/description/banner.png differ diff --git a/product_volume/static/description/cybro_logo.png b/product_volume/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/product_volume/static/description/cybro_logo.png differ diff --git a/product_volume/static/description/icon.png b/product_volume/static/description/icon.png new file mode 100644 index 000000000..6e02c5aeb Binary files /dev/null and b/product_volume/static/description/icon.png differ diff --git a/product_volume/static/description/images/banner_lifeline_for_task.jpeg b/product_volume/static/description/images/banner_lifeline_for_task.jpeg new file mode 100644 index 000000000..4a467ea22 Binary files /dev/null and b/product_volume/static/description/images/banner_lifeline_for_task.jpeg differ diff --git a/product_volume/static/description/images/banner_project_report_xls_pdf.png b/product_volume/static/description/images/banner_project_report_xls_pdf.png new file mode 100644 index 000000000..3c430a7eb Binary files /dev/null and b/product_volume/static/description/images/banner_project_report_xls_pdf.png differ diff --git a/product_volume/static/description/images/banner_project_status_report.png b/product_volume/static/description/images/banner_project_status_report.png new file mode 100644 index 000000000..d1b689710 Binary files /dev/null and b/product_volume/static/description/images/banner_project_status_report.png differ diff --git a/product_volume/static/description/images/banner_subtask.jpeg b/product_volume/static/description/images/banner_subtask.jpeg new file mode 100644 index 000000000..f2b224110 Binary files /dev/null and b/product_volume/static/description/images/banner_subtask.jpeg differ diff --git a/product_volume/static/description/images/banner_task_deadline_reminder.jpeg b/product_volume/static/description/images/banner_task_deadline_reminder.jpeg new file mode 100644 index 000000000..998679818 Binary files /dev/null and b/product_volume/static/description/images/banner_task_deadline_reminder.jpeg differ diff --git a/product_volume/static/description/images/banner_task_statusbar.jpeg b/product_volume/static/description/images/banner_task_statusbar.jpeg new file mode 100644 index 000000000..2c57cbb7b Binary files /dev/null and b/product_volume/static/description/images/banner_task_statusbar.jpeg differ diff --git a/product_volume/static/description/images/checked.png b/product_volume/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/product_volume/static/description/images/checked.png differ diff --git a/product_volume/static/description/images/cybrosys.png b/product_volume/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/product_volume/static/description/images/cybrosys.png differ diff --git a/product_volume/static/description/images/product volume.png b/product_volume/static/description/images/product volume.png new file mode 100644 index 000000000..efdebe23a Binary files /dev/null and b/product_volume/static/description/images/product volume.png differ diff --git a/product_volume/static/description/images/product_volume.png b/product_volume/static/description/images/product_volume.png new file mode 100644 index 000000000..7c003000b Binary files /dev/null and b/product_volume/static/description/images/product_volume.png differ diff --git a/product_volume/static/description/index.html b/product_volume/static/description/index.html new file mode 100644 index 000000000..b9450eeef --- /dev/null +++ b/product_volume/static/description/index.html @@ -0,0 +1,282 @@ +
cybrosys-logo
+
+
+
+

Product Volume Calculation

+

Calculates the product volume

+
+

Key Highlights

+
    +
  • Seamless adding of properties- Length, Breadth and Height of the product in the product master page
  • +
  • Automatic calculation of volume with the above details
  • +
+
+
+
+ +
+
+
+
+ +
+
+ +

Overview

+
+

+ The module provisions to add the length, breadth and height of the chosen product. It also enables the end user to perform automatic volume calculation of the product.

+
+ + + +
+ +

Product Volume Calculation

+
+
    +

    + Seamless adding of properties- Length, Breadth and Height of the product in the product master page +

    + +

    + Automatic calculation of volume with the above details +

    +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/product_volume/views/volume_view.xml b/product_volume/views/volume_view.xml new file mode 100644 index 000000000..f38f17175 --- /dev/null +++ b/product_volume/views/volume_view.xml @@ -0,0 +1,30 @@ + + + + + product.template.volume + product.template + + + + + + + + + + diff --git a/purchase_orderline_image/README.rst b/purchase_orderline_image/README.rst new file mode 100644 index 000000000..e2202a361 --- /dev/null +++ b/purchase_orderline_image/README.rst @@ -0,0 +1,20 @@ +Purchase Order Line Images +========================== +Order Line Images In Purchase + +Installation +============ + - www.odoo.com/documentation/13.0/setup/install.html + - Install our custom addon + +Configuration +============= + + - No additional configurations needed + +Credits +------- +* Developer: Anusha @ Cybrosys + V14 Muhammed Nafih @ Cybrosys + + diff --git a/purchase_orderline_image/__init__.py b/purchase_orderline_image/__init__.py new file mode 100644 index 000000000..9d876ea62 --- /dev/null +++ b/purchase_orderline_image/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from . import models diff --git a/purchase_orderline_image/__manifest__.py b/purchase_orderline_image/__manifest__.py new file mode 100644 index 000000000..26db23f2a --- /dev/null +++ b/purchase_orderline_image/__manifest__.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +{ + "name": "Purchase Order Line Images", + "summary": "Order Line Images In Purchase and Report", + "description": """Order Line Images In Purchase and Report""", + "version": "14.0.1.0.0", + "category": 'Purchase/Purchase', + "website": "https://www.cybrosys.com", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + "depends": [ + 'purchase', + ], + "data": [ + 'views/purchase_order_line_image.xml', + 'views/res_config_settings.xml', + 'report/purchase_order_report.xml', + ], + 'images': ['static/description/banner.png'], + 'license': 'LGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/purchase_orderline_image/doc/RELEASE_NOTES.md b/purchase_orderline_image/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..01de9d152 --- /dev/null +++ b/purchase_orderline_image/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 04.01.2020 +#### Version 14.0.1.0.0 +##### ADD +- Initial commit for Purchase Order Line Images diff --git a/purchase_orderline_image/models/__init__.py b/purchase_orderline_image/models/__init__.py new file mode 100644 index 000000000..249491a8c --- /dev/null +++ b/purchase_orderline_image/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import purchase_order_line_image +from . import res_config_settings diff --git a/purchase_orderline_image/models/purchase_order_line_image.py b/purchase_orderline_image/models/purchase_order_line_image.py new file mode 100644 index 000000000..9b6eb19d5 --- /dev/null +++ b/purchase_orderline_image/models/purchase_order_line_image.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from odoo import fields, models + + +class PurchaseOrderLine(models.Model): + _inherit = 'purchase.order.line' + + order_line_image = fields.Binary(string="Image", + related="product_id.image_1920") diff --git a/purchase_orderline_image/models/res_config_settings.py b/purchase_orderline_image/models/res_config_settings.py new file mode 100644 index 000000000..f5dc3b8c1 --- /dev/null +++ b/purchase_orderline_image/models/res_config_settings.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import fields, models,api + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + show_product_image_in_report_purchase = fields.Boolean(string="Show Product Image", default=False) + + @api.model + def set_values(self): + self.env['ir.config_parameter'].sudo().set_param('purchase_orderline_image.show_product_image_in_report_purchase', + self.show_product_image_in_report_purchase) + res = super(ResConfigSettings, self).set_values() + return res + + def get_values(self): + res = super(ResConfigSettings, self).get_values() + param = self.env['ir.config_parameter'].sudo().get_param( + 'purchase_orderline_image.show_product_image_in_report_purchase', + self.show_product_image_in_report_purchase) + res.update( + show_product_image_in_report_purchase=param + ) + return res diff --git a/purchase_orderline_image/report/purchase_order_report.xml b/purchase_orderline_image/report/purchase_order_report.xml new file mode 100644 index 000000000..33ec3c893 --- /dev/null +++ b/purchase_orderline_image/report/purchase_order_report.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/purchase_orderline_image/static/description/banner.png b/purchase_orderline_image/static/description/banner.png new file mode 100644 index 000000000..321f90992 Binary files /dev/null and b/purchase_orderline_image/static/description/banner.png differ diff --git a/purchase_orderline_image/static/description/icon.png b/purchase_orderline_image/static/description/icon.png new file mode 100644 index 000000000..d93fec98c Binary files /dev/null and b/purchase_orderline_image/static/description/icon.png differ diff --git a/purchase_orderline_image/static/description/images/banner_barcode_scanning.jpeg b/purchase_orderline_image/static/description/images/banner_barcode_scanning.jpeg new file mode 100644 index 000000000..529143e4e Binary files /dev/null and b/purchase_orderline_image/static/description/images/banner_barcode_scanning.jpeg differ diff --git a/purchase_orderline_image/static/description/images/banner_currency_total.png b/purchase_orderline_image/static/description/images/banner_currency_total.png new file mode 100644 index 000000000..6153ed719 Binary files /dev/null and b/purchase_orderline_image/static/description/images/banner_currency_total.png differ diff --git a/purchase_orderline_image/static/description/images/banner_customer_sequence.jpeg b/purchase_orderline_image/static/description/images/banner_customer_sequence.jpeg new file mode 100644 index 000000000..7451342d6 Binary files /dev/null and b/purchase_orderline_image/static/description/images/banner_customer_sequence.jpeg differ diff --git a/purchase_orderline_image/static/description/images/banner_previous_rates.jpeg b/purchase_orderline_image/static/description/images/banner_previous_rates.jpeg new file mode 100644 index 000000000..e10c28799 Binary files /dev/null and b/purchase_orderline_image/static/description/images/banner_previous_rates.jpeg differ diff --git a/purchase_orderline_image/static/description/images/banner_product_branding.png b/purchase_orderline_image/static/description/images/banner_product_branding.png new file mode 100644 index 000000000..aa12beabb Binary files /dev/null and b/purchase_orderline_image/static/description/images/banner_product_branding.png differ diff --git a/purchase_orderline_image/static/description/images/banner_product_expiry.jpeg b/purchase_orderline_image/static/description/images/banner_product_expiry.jpeg new file mode 100644 index 000000000..84a872d44 Binary files /dev/null and b/purchase_orderline_image/static/description/images/banner_product_expiry.jpeg differ diff --git a/purchase_orderline_image/static/description/images/checked.png b/purchase_orderline_image/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/purchase_orderline_image/static/description/images/checked.png differ diff --git a/purchase_orderline_image/static/description/images/cybrosys.png b/purchase_orderline_image/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/purchase_orderline_image/static/description/images/cybrosys.png differ diff --git a/purchase_orderline_image/static/description/images/purchase_line_1.png b/purchase_orderline_image/static/description/images/purchase_line_1.png new file mode 100644 index 000000000..fb44c3987 Binary files /dev/null and b/purchase_orderline_image/static/description/images/purchase_line_1.png differ diff --git a/purchase_orderline_image/static/description/images/purchase_order.png b/purchase_orderline_image/static/description/images/purchase_order.png new file mode 100644 index 000000000..e2d61ae7f Binary files /dev/null and b/purchase_orderline_image/static/description/images/purchase_order.png differ diff --git a/purchase_orderline_image/static/description/images/purchase_order_line_2.png b/purchase_orderline_image/static/description/images/purchase_order_line_2.png new file mode 100644 index 000000000..5dc9c3338 Binary files /dev/null and b/purchase_orderline_image/static/description/images/purchase_order_line_2.png differ diff --git a/purchase_orderline_image/static/description/images/purchase_order_line_3.png b/purchase_orderline_image/static/description/images/purchase_order_line_3.png new file mode 100644 index 000000000..7c895f166 Binary files /dev/null and b/purchase_orderline_image/static/description/images/purchase_order_line_3.png differ diff --git a/purchase_orderline_image/static/description/index.html b/purchase_orderline_image/static/description/index.html new file mode 100644 index 000000000..c23d5eca7 --- /dev/null +++ b/purchase_orderline_image/static/description/index.html @@ -0,0 +1,497 @@ +
+ cybrosys-logo
+
+
+
+

Purchase Order Line Images

+

Order Line Image In Purchase Order.

+
+

Key Highlights

+
    +
  • + Product images in order line. +
  • +
  • + Print product images in report. +
  • +
+
+
+
+
+
+
+
+ +
+
+ +

Overview

+
+

+ This app allows you see the product images in purchase order line and also allow us + to print the product image in report. +

+
+
+ +

Features

+
+
    +
  • + Order line product images. +
  • +
  • + Print product images in report. +
  • +
  • + Configure the image printing option. +
  • +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+
+ Odoo Industry
+
+
+

+ + Trading

+

+ Easily procure and sell your products.

+
+
+
+
+
+ Odoo Industry +
+
+
+

+ + Manufacturing

+

+ Plan, track and schedule your operations.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Restaurant

+

+ Run your bar or restaurant methodical.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + POS

+

+ Easy configuring and convivial selling.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + E-commerce & Website

+

+ Mobile friendly, awe-inspiring product pages.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Hotel Management

+

+ An all-inclusive hotel management application.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Education

+

+ A Collaborative platform for educational management.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + Service Management

+

+ Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please + let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/purchase_orderline_image/views/purchase_order_line_image.xml b/purchase_orderline_image/views/purchase_order_line_image.xml new file mode 100644 index 000000000..94707a11f --- /dev/null +++ b/purchase_orderline_image/views/purchase_order_line_image.xml @@ -0,0 +1,16 @@ + + + + + purchase.order.inherit.form.view + purchase.order + + + + + + + + + \ No newline at end of file diff --git a/purchase_orderline_image/views/res_config_settings.xml b/purchase_orderline_image/views/res_config_settings.xml new file mode 100644 index 000000000..3fe3cfaa7 --- /dev/null +++ b/purchase_orderline_image/views/res_config_settings.xml @@ -0,0 +1,24 @@ + + + + res.config.settings.view.form.inherit.purchase + res.config.settings + + + +
+
+ +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/sales_person_signature/README.rst b/sales_person_signature/README.rst new file mode 100644 index 000000000..685bb9b18 --- /dev/null +++ b/sales_person_signature/README.rst @@ -0,0 +1,40 @@ +Salesperson Signature +===================== +* Enables the option for adding the salesperson signature in sales, purchase and invoicing + +Installation +============ +- www.odoo.com/documentation/13.0/setup/install.html +- Install our custom addon + +License +------- +GNU AFFERO GENERAL PUBLIC LICENSE, Version 3 (AGPLv3) +(http://www.gnu.org/licenses/agpl.html) + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developer: Sayooj A O + V14 Muhammed Nafih + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com + +Further information +=================== +HTML Description: ``__ diff --git a/sales_person_signature/__init__.py b/sales_person_signature/__init__.py new file mode 100644 index 000000000..2ac9ce16c --- /dev/null +++ b/sales_person_signature/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import models diff --git a/sales_person_signature/__manifest__.py b/sales_person_signature/__manifest__.py new file mode 100644 index 000000000..ce86bce0b --- /dev/null +++ b/sales_person_signature/__manifest__.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# + +{ + 'name': "Salesperson Signature", + 'version': '14.0.1.0.0', + 'summary': """In this module allows the salesperson to add his signature and also + available the option for making the validate option in sales + visible/invisible based on the salesperson signature""", + 'description': """In this module allows the salesperson to add his signature and also + available the option for making the validate option in sales + visible/invisible based on the salesperson signature""", + 'category': 'Sales', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['base', 'sale_management'], + 'data': [ + 'views/sale_signature.xml', + 'views/res_config_settings_inherited.xml', + ], + 'license': "AGPL-3", + 'images': ['static/description/banner.png'], + 'installable': True, + 'application': True, +} diff --git a/sales_person_signature/doc/RELEASE_NOTES.md b/sales_person_signature/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..d789f2247 --- /dev/null +++ b/sales_person_signature/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 06.01.2020 +#### Version 14.0.1.0.0 +##### ADD +- Initial commit diff --git a/sales_person_signature/models/__init__.py b/sales_person_signature/models/__init__.py new file mode 100644 index 000000000..195e66c31 --- /dev/null +++ b/sales_person_signature/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import sale +from . import res_config_settings diff --git a/sales_person_signature/models/res_config_settings.py b/sales_person_signature/models/res_config_settings.py new file mode 100644 index 000000000..3cd9b5f7f --- /dev/null +++ b/sales_person_signature/models/res_config_settings.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + sale_document_approve = fields.Boolean(config_parameter='sale.sale_document_approve') \ No newline at end of file diff --git a/sales_person_signature/models/sale.py b/sales_person_signature/models/sale.py new file mode 100644 index 000000000..6d0008a8b --- /dev/null +++ b/sales_person_signature/models/sale.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import models, fields, api + + +class SaleOrderLine(models.Model): + """In this class we are inheriting the model sale.order and adding + a new field for signature""" + + _inherit = 'sale.order' + + sale_person_signature = fields.Binary(string='Signature', help="Field for adding the signature of the sales person") + check_signature = fields.Boolean(compute='_compute_check_signature') + + @api.depends('sale_person_signature') + def _compute_check_signature(self): + """In this function computes the value of the boolean field check signature + which is used to hide/unhide the validate button in the current document""" + if self.env['ir.config_parameter'].sudo().get_param('sale.sale_document_approve'): + if self.sale_person_signature: + self.check_signature = True + else: + self.check_signature = False + else: + self.check_signature = True diff --git a/sales_person_signature/static/description/banner.png b/sales_person_signature/static/description/banner.png new file mode 100644 index 000000000..986534869 Binary files /dev/null and b/sales_person_signature/static/description/banner.png differ diff --git a/sales_person_signature/static/description/icon.png b/sales_person_signature/static/description/icon.png new file mode 100644 index 000000000..2c1d3c3ee Binary files /dev/null and b/sales_person_signature/static/description/icon.png differ diff --git a/sales_person_signature/static/description/images/banner_barcode_scanning.jpeg b/sales_person_signature/static/description/images/banner_barcode_scanning.jpeg new file mode 100644 index 000000000..529143e4e Binary files /dev/null and b/sales_person_signature/static/description/images/banner_barcode_scanning.jpeg differ diff --git a/sales_person_signature/static/description/images/banner_currency_total.png b/sales_person_signature/static/description/images/banner_currency_total.png new file mode 100644 index 000000000..6153ed719 Binary files /dev/null and b/sales_person_signature/static/description/images/banner_currency_total.png differ diff --git a/sales_person_signature/static/description/images/banner_customer_sequence.jpeg b/sales_person_signature/static/description/images/banner_customer_sequence.jpeg new file mode 100644 index 000000000..7451342d6 Binary files /dev/null and b/sales_person_signature/static/description/images/banner_customer_sequence.jpeg differ diff --git a/sales_person_signature/static/description/images/banner_previous_rates.jpeg b/sales_person_signature/static/description/images/banner_previous_rates.jpeg new file mode 100644 index 000000000..e10c28799 Binary files /dev/null and b/sales_person_signature/static/description/images/banner_previous_rates.jpeg differ diff --git a/sales_person_signature/static/description/images/banner_product_branding.png b/sales_person_signature/static/description/images/banner_product_branding.png new file mode 100644 index 000000000..aa12beabb Binary files /dev/null and b/sales_person_signature/static/description/images/banner_product_branding.png differ diff --git a/sales_person_signature/static/description/images/banner_product_expiry.jpeg b/sales_person_signature/static/description/images/banner_product_expiry.jpeg new file mode 100644 index 000000000..84a872d44 Binary files /dev/null and b/sales_person_signature/static/description/images/banner_product_expiry.jpeg differ diff --git a/sales_person_signature/static/description/images/checked.png b/sales_person_signature/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/sales_person_signature/static/description/images/checked.png differ diff --git a/sales_person_signature/static/description/images/cybrosys.png b/sales_person_signature/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/sales_person_signature/static/description/images/cybrosys.png differ diff --git a/sales_person_signature/static/description/images/sale_person_signature_gif.png b/sales_person_signature/static/description/images/sale_person_signature_gif.png new file mode 100644 index 000000000..e1894a9c8 Binary files /dev/null and b/sales_person_signature/static/description/images/sale_person_signature_gif.png differ diff --git a/sales_person_signature/static/description/images/sales_person_signature-01.png b/sales_person_signature/static/description/images/sales_person_signature-01.png new file mode 100644 index 000000000..47277537d Binary files /dev/null and b/sales_person_signature/static/description/images/sales_person_signature-01.png differ diff --git a/sales_person_signature/static/description/images/sales_person_signature-02.png b/sales_person_signature/static/description/images/sales_person_signature-02.png new file mode 100644 index 000000000..42f81fdb3 Binary files /dev/null and b/sales_person_signature/static/description/images/sales_person_signature-02.png differ diff --git a/sales_person_signature/static/description/images/sales_person_signature-03.png b/sales_person_signature/static/description/images/sales_person_signature-03.png new file mode 100644 index 000000000..baace2120 Binary files /dev/null and b/sales_person_signature/static/description/images/sales_person_signature-03.png differ diff --git a/sales_person_signature/static/description/images/sales_person_signature-04.png b/sales_person_signature/static/description/images/sales_person_signature-04.png new file mode 100644 index 000000000..2e3daa58b Binary files /dev/null and b/sales_person_signature/static/description/images/sales_person_signature-04.png differ diff --git a/sales_person_signature/static/description/images/sales_person_signature-05.png b/sales_person_signature/static/description/images/sales_person_signature-05.png new file mode 100644 index 000000000..53e5611cd Binary files /dev/null and b/sales_person_signature/static/description/images/sales_person_signature-05.png differ diff --git a/sales_person_signature/static/description/images/sales_person_signature-06.png b/sales_person_signature/static/description/images/sales_person_signature-06.png new file mode 100644 index 000000000..8731c5f98 Binary files /dev/null and b/sales_person_signature/static/description/images/sales_person_signature-06.png differ diff --git a/sales_person_signature/static/description/index.html b/sales_person_signature/static/description/index.html new file mode 100644 index 000000000..2aee1da32 --- /dev/null +++ b/sales_person_signature/static/description/index.html @@ -0,0 +1,317 @@ +
cybrosys-logo
+
+
+
+

Salesperson Signature

+

Add salesperson's signature in Sales documents.

+
+

Key Highlights

+
    +
  • Add salesperson's signature in Sales document.
  • +
  • Enables option to keep visible/invisible the validation of the corresponding documents based on signature.
  • +
  • Validation based on signature can be enabled/disabled from the settings.
  • +
+
+
+
+
+
+
+
+ +
+
+ +

Overview

+
+

+ The module allows the salesperson's to add his signature and also available the option for making the validate option in sales visible/invisible based on the salesperson's signature +

+
+
+ +

Partner Custom Fields

+
+
    +
  • + Add salesperson's signature in Sales documents. +
  • +
  • + Option for making the validate option visible/invisible of the corresponding documents based on signature. +
  • +
  • + Validation based on signature can be enable/disable from the settings. +
  • +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/sales_person_signature/views/res_config_settings_inherited.xml b/sales_person_signature/views/res_config_settings_inherited.xml new file mode 100644 index 000000000..041fbf8d2 --- /dev/null +++ b/sales_person_signature/views/res_config_settings_inherited.xml @@ -0,0 +1,27 @@ + + + + res.config.settings.view.form.inherit.sale.approval + res.config.settings + + + + +

Sale Approval

+
+
+
+ +
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/sales_person_signature/views/sale_signature.xml b/sales_person_signature/views/sale_signature.xml new file mode 100644 index 000000000..fb9febf25 --- /dev/null +++ b/sales_person_signature/views/sale_signature.xml @@ -0,0 +1,22 @@ + + + + view.sale.order.signature.inherited + sale.order + + + + + + + + {'invisible': ['|',('state', 'not in', ['sent']),('check_signature','=',False)]} + + + + {'invisible':['|',('state', 'not in', ['draft']),('check_signature','=',False)]} + + + + + \ No newline at end of file diff --git a/stock_move_invoice/README.rst b/stock_move_invoice/README.rst new file mode 100644 index 000000000..d5b0c660b --- /dev/null +++ b/stock_move_invoice/README.rst @@ -0,0 +1,41 @@ +Invoice From Stock Picking +========================== +* Enables the option for creating invoice from stock picking + +Installation +============ +- www.odoo.com/documentation/14.0/setup/install.html +- Install our custom addon + +License +------- +GNU AFFERO GENERAL PUBLIC LICENSE, Version 3 (AGPLv3) +(http://www.gnu.org/licenses/agpl.html) + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developer: + V13 Sayooj A O + V14 Minhaj T + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com + +Further information +=================== +HTML Description: ``__ diff --git a/stock_move_invoice/__init__.py b/stock_move_invoice/__init__.py new file mode 100644 index 000000000..f5dbb7050 --- /dev/null +++ b/stock_move_invoice/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import models +from . import wizard diff --git a/stock_move_invoice/__manifest__.py b/stock_move_invoice/__manifest__.py new file mode 100644 index 000000000..3b20563a1 --- /dev/null +++ b/stock_move_invoice/__manifest__.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# + +{ + 'name': "Invoice From Stock Picking", + 'version': '14.0.1.0.0', + 'summary': """In this module creating customer invoice,vendor bill, customer + credit note and refund from stock picking""", + 'description': """In this module creating customer invoice,vendor bill, customer + credit note and refund from stock picking""", + 'category': 'Stock', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['stock', 'account'], + 'data': [ + 'views/account_move_inherited.xml', + 'views/stock_picking_inherited.xml', + 'views/res_config_settings_inherited.xml', + 'wizard/picking_invoice_wizard.xml', + ], + 'license': "AGPL-3", + 'images': ['static/description/banner.png'], + 'installable': True, + 'application': True, +} diff --git a/stock_move_invoice/doc/RELEASE_NOTES.md b/stock_move_invoice/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..f01721a60 --- /dev/null +++ b/stock_move_invoice/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 22.10.2020 +#### Version 14.0.1.0.0 +##### ADD +- Initial commit diff --git a/stock_move_invoice/models/__init__.py b/stock_move_invoice/models/__init__.py new file mode 100644 index 000000000..218cd9fba --- /dev/null +++ b/stock_move_invoice/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import account_move +from . import res_config_settings +from . import stock_picking diff --git a/stock_move_invoice/models/account_move.py b/stock_move_invoice/models/account_move.py new file mode 100644 index 000000000..a30b36df9 --- /dev/null +++ b/stock_move_invoice/models/account_move.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import api, fields, models + + +class AccountMove(models.Model): + _inherit = 'account.move' + + picking_id = fields.Many2one('stock.picking', string='Picking') diff --git a/stock_move_invoice/models/res_config_settings.py b/stock_move_invoice/models/res_config_settings.py new file mode 100644 index 000000000..e43712180 --- /dev/null +++ b/stock_move_invoice/models/res_config_settings.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import fields, models + + +class Settings(models.TransientModel): + _inherit = 'res.config.settings' + customer_journal_id = fields.Many2one('account.journal', string='Customer Journal', + config_parameter='stock_move_invoice.customer_journal_id') + vendor_journal_id = fields.Many2one('account.journal', string='Vendor Journal', + config_parameter='stock_move_invoice.vendor_journal_id') diff --git a/stock_move_invoice/models/stock_picking.py b/stock_move_invoice/models/stock_picking.py new file mode 100644 index 000000000..d8142be78 --- /dev/null +++ b/stock_move_invoice/models/stock_picking.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Sayooj A O() +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import fields, models, _ +from odoo.exceptions import UserError + + +class StockPicking(models.Model): + _inherit = 'stock.picking' + invoice_count = fields.Integer(string='Invoices', compute='_compute_invoice_count') + operation_code = fields.Selection(related='picking_type_id.code') + is_return = fields.Boolean() + + def _compute_invoice_count(self): + """This compute function used to count the number of invoice for the picking""" + for picking_id in self: + move_ids = picking_id.env['account.move'].search([('invoice_origin', '=', picking_id.name)]) + if move_ids: + self.invoice_count = len(move_ids) + else: + self.invoice_count = 0 + + def create_invoice(self): + """This is the function for creating customer invoice + from the picking""" + for picking_id in self: + current_user = self.env.uid + if picking_id.picking_type_id.code == 'outgoing': + customer_journal_id = picking_id.env['ir.config_parameter'].sudo().get_param( + 'stock_move_invoice.customer_journal_id') or False + if not customer_journal_id: + raise UserError(_("Please configure the journal from settings")) + invoice_line_list = [] + for move_ids_without_package in picking_id.move_ids_without_package: + vals = (0, 0, { + 'name': move_ids_without_package.description_picking, + 'product_id': move_ids_without_package.product_id.id, + 'price_unit': move_ids_without_package.product_id.lst_price, + 'account_id': move_ids_without_package.product_id.property_account_income_id.id if move_ids_without_package.product_id.property_account_income_id + else move_ids_without_package.product_id.categ_id.property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [picking_id.company_id.account_sale_tax_id.id])], + 'quantity': move_ids_without_package.quantity_done, + }) + invoice_line_list.append(vals) + invoice = picking_id.env['account.move'].create({ + 'move_type': 'out_invoice', + 'invoice_origin': picking_id.name, + 'invoice_user_id': current_user, + 'narration': picking_id.name, + 'partner_id': picking_id.partner_id.id, + 'currency_id': picking_id.env.user.company_id.currency_id.id, + 'journal_id': int(customer_journal_id), + 'payment_reference': picking_id.name, + 'picking_id': picking_id.id, + 'invoice_line_ids': invoice_line_list + }) + return invoice + + def create_bill(self): + """This is the function for creating vendor bill + from the picking""" + for picking_id in self: + current_user = self.env.uid + if picking_id.picking_type_id.code == 'incoming': + vendor_journal_id = picking_id.env['ir.config_parameter'].sudo().get_param( + 'stock_move_invoice.vendor_journal_id') or False + if not vendor_journal_id: + raise UserError(_("Please configure the journal from the settings.")) + invoice_line_list = [] + for move_ids_without_package in picking_id.move_ids_without_package: + vals = (0, 0, { + 'name': move_ids_without_package.description_picking, + 'product_id': move_ids_without_package.product_id.id, + 'price_unit': move_ids_without_package.product_id.lst_price, + 'account_id': move_ids_without_package.product_id.property_account_income_id.id if move_ids_without_package.product_id.property_account_income_id + else move_ids_without_package.product_id.categ_id.property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [picking_id.company_id.account_purchase_tax_id.id])], + 'quantity': move_ids_without_package.quantity_done, + }) + invoice_line_list.append(vals) + invoice = picking_id.env['account.move'].create({ + 'move_type': 'in_invoice', + 'invoice_origin': picking_id.name, + 'invoice_user_id': current_user, + 'narration': picking_id.name, + 'partner_id': picking_id.partner_id.id, + 'currency_id': picking_id.env.user.company_id.currency_id.id, + 'journal_id': int(vendor_journal_id), + 'payment_reference': picking_id.name, + 'picking_id': picking_id.id, + 'invoice_line_ids': invoice_line_list + }) + return invoice + + def create_customer_credit(self): + """This is the function for creating customer credit note + from the picking""" + for picking_id in self: + current_user = picking_id.env.uid + if picking_id.picking_type_id.code == 'incoming': + customer_journal_id = picking_id.env['ir.config_parameter'].sudo().get_param( + 'stock_move_invoice.customer_journal_id') or False + if not customer_journal_id: + raise UserError(_("Please configure the journal from settings")) + invoice_line_list = [] + for move_ids_without_package in picking_id.move_ids_without_package: + vals = (0, 0, { + 'name': move_ids_without_package.description_picking, + 'product_id': move_ids_without_package.product_id.id, + 'price_unit': move_ids_without_package.product_id.lst_price, + 'account_id': move_ids_without_package.product_id.property_account_income_id.id if move_ids_without_package.product_id.property_account_income_id + else move_ids_without_package.product_id.categ_id.property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [picking_id.company_id.account_sale_tax_id.id])], + 'quantity': move_ids_without_package.quantity_done, + }) + invoice_line_list.append(vals) + invoice = picking_id.env['account.move'].create({ + 'move_type': 'out_refund', + 'invoice_origin': picking_id.name, + 'invoice_user_id': current_user, + 'narration': picking_id.name, + 'partner_id': picking_id.partner_id.id, + 'currency_id': picking_id.env.user.company_id.currency_id.id, + 'journal_id': int(customer_journal_id), + 'payment_reference': picking_id.name, + 'picking_id': picking_id.id, + 'invoice_line_ids': invoice_line_list + }) + return invoice + + def create_vendor_credit(self): + """This is the function for creating refund + from the picking""" + for picking_id in self: + current_user = self.env.uid + if picking_id.picking_type_id.code == 'outgoing': + vendor_journal_id = picking_id.env['ir.config_parameter'].sudo().get_param( + 'stock_move_invoice.vendor_journal_id') or False + if not vendor_journal_id: + raise UserError(_("Please configure the journal from the settings.")) + invoice_line_list = [] + for move_ids_without_package in picking_id.move_ids_without_package: + vals = (0, 0, { + 'name': move_ids_without_package.description_picking, + 'product_id': move_ids_without_package.product_id.id, + 'price_unit': move_ids_without_package.product_id.lst_price, + 'account_id': move_ids_without_package.product_id.property_account_income_id.id if move_ids_without_package.product_id.property_account_income_id + else move_ids_without_package.product_id.categ_id.property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [picking_id.company_id.account_purchase_tax_id.id])], + 'quantity': move_ids_without_package.quantity_done, + }) + invoice_line_list.append(vals) + invoice = picking_id.env['account.move'].create({ + 'move_type': 'in_refund', + 'invoice_origin': picking_id.name, + 'invoice_user_id': current_user, + 'narration': picking_id.name, + 'partner_id': picking_id.partner_id.id, + 'currency_id': picking_id.env.user.company_id.currency_id.id, + 'journal_id': int(vendor_journal_id), + 'payment_reference': picking_id.name, + 'picking_id': picking_id.id, + 'invoice_line_ids': invoice_line_list + }) + return invoice + + def action_open_picking_invoice(self): + """This is the function of the smart button which redirect to the + invoice related to the current picking""" + return { + 'name': 'Invoices', + 'type': 'ir.actions.act_window', + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'domain': [('invoice_origin', '=', self.name)], + 'context': {'create': False}, + 'target': 'current' + } + + +class StockReturnInvoicePicking(models.TransientModel): + _inherit = 'stock.return.picking' + + def _create_returns(self): + """in this function the picking is marked as return""" + new_picking, pick_type_id = super(StockReturnInvoicePicking, self)._create_returns() + picking = self.env['stock.picking'].browse(new_picking) + picking.write({'is_return': True}) + return new_picking, pick_type_id diff --git a/stock_move_invoice/security/ir.model.access.csv b/stock_move_invoice/security/ir.model.access.csv new file mode 100644 index 000000000..5fc94b439 --- /dev/null +++ b/stock_move_invoice/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_picking_invoice_wizard_manager_id,access_picking_invoice_wizard_manager,model_picking_invoice_wizard,base.group_erp_manager,1,1,1,1 +access_picking_invoice_wizard_user_id,access_picking_invoice_wizard_user,model_picking_invoice_wizard,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/stock_move_invoice/static/description/banner.png b/stock_move_invoice/static/description/banner.png new file mode 100644 index 000000000..4ca62ed5f Binary files /dev/null and b/stock_move_invoice/static/description/banner.png differ diff --git a/stock_move_invoice/static/description/icon.png b/stock_move_invoice/static/description/icon.png new file mode 100644 index 000000000..7b7bc514e Binary files /dev/null and b/stock_move_invoice/static/description/icon.png differ diff --git a/stock_move_invoice/static/description/images/banner_barcode_scanning.jpeg b/stock_move_invoice/static/description/images/banner_barcode_scanning.jpeg new file mode 100644 index 000000000..529143e4e Binary files /dev/null and b/stock_move_invoice/static/description/images/banner_barcode_scanning.jpeg differ diff --git a/stock_move_invoice/static/description/images/banner_currency_total.png b/stock_move_invoice/static/description/images/banner_currency_total.png new file mode 100644 index 000000000..6153ed719 Binary files /dev/null and b/stock_move_invoice/static/description/images/banner_currency_total.png differ diff --git a/stock_move_invoice/static/description/images/banner_customer_sequence.jpeg b/stock_move_invoice/static/description/images/banner_customer_sequence.jpeg new file mode 100644 index 000000000..7451342d6 Binary files /dev/null and b/stock_move_invoice/static/description/images/banner_customer_sequence.jpeg differ diff --git a/stock_move_invoice/static/description/images/banner_previous_rates.jpeg b/stock_move_invoice/static/description/images/banner_previous_rates.jpeg new file mode 100644 index 000000000..e10c28799 Binary files /dev/null and b/stock_move_invoice/static/description/images/banner_previous_rates.jpeg differ diff --git a/stock_move_invoice/static/description/images/banner_product_branding.png b/stock_move_invoice/static/description/images/banner_product_branding.png new file mode 100644 index 000000000..aa12beabb Binary files /dev/null and b/stock_move_invoice/static/description/images/banner_product_branding.png differ diff --git a/stock_move_invoice/static/description/images/banner_product_expiry.jpeg b/stock_move_invoice/static/description/images/banner_product_expiry.jpeg new file mode 100644 index 000000000..84a872d44 Binary files /dev/null and b/stock_move_invoice/static/description/images/banner_product_expiry.jpeg differ diff --git a/stock_move_invoice/static/description/images/checked.png b/stock_move_invoice/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/stock_move_invoice/static/description/images/checked.png differ diff --git a/stock_move_invoice/static/description/images/cybrosys.png b/stock_move_invoice/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/stock_move_invoice/static/description/images/cybrosys.png differ diff --git a/stock_move_invoice/static/description/images/invoice_picking.png b/stock_move_invoice/static/description/images/invoice_picking.png new file mode 100644 index 000000000..4bada43ce Binary files /dev/null and b/stock_move_invoice/static/description/images/invoice_picking.png differ diff --git a/stock_move_invoice/static/description/images/stock_move_invoice-1.png b/stock_move_invoice/static/description/images/stock_move_invoice-1.png new file mode 100644 index 000000000..d394185ff Binary files /dev/null and b/stock_move_invoice/static/description/images/stock_move_invoice-1.png differ diff --git a/stock_move_invoice/static/description/images/stock_move_invoice-2.png b/stock_move_invoice/static/description/images/stock_move_invoice-2.png new file mode 100644 index 000000000..f0f9e5510 Binary files /dev/null and b/stock_move_invoice/static/description/images/stock_move_invoice-2.png differ diff --git a/stock_move_invoice/static/description/images/stock_move_invoice-3.png b/stock_move_invoice/static/description/images/stock_move_invoice-3.png new file mode 100644 index 000000000..2ab2a42b5 Binary files /dev/null and b/stock_move_invoice/static/description/images/stock_move_invoice-3.png differ diff --git a/stock_move_invoice/static/description/images/stock_move_invoice-4.png b/stock_move_invoice/static/description/images/stock_move_invoice-4.png new file mode 100644 index 000000000..311e616ef Binary files /dev/null and b/stock_move_invoice/static/description/images/stock_move_invoice-4.png differ diff --git a/stock_move_invoice/static/description/images/stock_move_invoice-5.png b/stock_move_invoice/static/description/images/stock_move_invoice-5.png new file mode 100644 index 000000000..dab7f4060 Binary files /dev/null and b/stock_move_invoice/static/description/images/stock_move_invoice-5.png differ diff --git a/stock_move_invoice/static/description/images/stock_move_invoice-6.png b/stock_move_invoice/static/description/images/stock_move_invoice-6.png new file mode 100644 index 000000000..5672ad310 Binary files /dev/null and b/stock_move_invoice/static/description/images/stock_move_invoice-6.png differ diff --git a/stock_move_invoice/static/description/images/stock_move_invoice-7.png b/stock_move_invoice/static/description/images/stock_move_invoice-7.png new file mode 100644 index 000000000..6f3b0eb75 Binary files /dev/null and b/stock_move_invoice/static/description/images/stock_move_invoice-7.png differ diff --git a/stock_move_invoice/static/description/index.html b/stock_move_invoice/static/description/index.html new file mode 100644 index 000000000..75004226c --- /dev/null +++ b/stock_move_invoice/static/description/index.html @@ -0,0 +1,549 @@ +
+ cybrosys-logo
+
+
+
+

Invoice From Stock Picking

+

Module for creating customer invoice,vendor bill, + credit note and refund from stock picking.

+
+

Key Highlights

+
    +
  • checkCreating invoice,bill,credit note and refund from individual picking. +
  • +
  • checkCreating invoice documents by selecting multiple documents. +
  • +
  • checkOption for configuring the journals from the settings. +
  • +
+
+
+
+
+
+
+
+ +
+
+ +

Overview

+
+

+ This module helps to create invoice,bill,credit note and refund from individual picking. +

+
+
+ +

Invoice From Stock Picking

+
+
    +
  • + + Creating invoice documents by selecting multiple documents. +
  • +
  • + Option for configuring the journals from the settings. +
  • + +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+
+ Odoo Industry
+
+
+

+ + Trading

+

+ Easily procure and sell your products.

+
+
+
+
+
+ Odoo Industry +
+
+
+

+ + Manufacturing

+

+ Plan, track and schedule your operations.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Restaurant

+

+ Run your bar or restaurant methodical.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + POS

+

+ Easy configuring and convivial selling.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + E-commerce & Website

+

+ Mobile friendly, awe-inspiring product pages.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Hotel Management

+

+ An all-inclusive hotel management application.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Education

+

+ A Collaborative platform for educational management.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + Service Management

+

+ Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please + let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/stock_move_invoice/views/account_move_inherited.xml b/stock_move_invoice/views/account_move_inherited.xml new file mode 100644 index 000000000..8eb74a27a --- /dev/null +++ b/stock_move_invoice/views/account_move_inherited.xml @@ -0,0 +1,15 @@ + + + + + account.move.form.view.inherited + account.move + + + + + + + + + \ No newline at end of file diff --git a/stock_move_invoice/views/res_config_settings_inherited.xml b/stock_move_invoice/views/res_config_settings_inherited.xml new file mode 100644 index 000000000..cf61956f4 --- /dev/null +++ b/stock_move_invoice/views/res_config_settings_inherited.xml @@ -0,0 +1,42 @@ + + + + res.config.settings.invoice.modification + res.config.settings + + + + +

Invoice From Stock Picking

+
+
+
+
+ Journals + +
+ Journals which should apply for the invoice creation from stock picking +
+
+
+
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/stock_move_invoice/views/stock_picking_inherited.xml b/stock_move_invoice/views/stock_picking_inherited.xml new file mode 100644 index 000000000..4c0a1708f --- /dev/null +++ b/stock_move_invoice/views/stock_picking_inherited.xml @@ -0,0 +1,37 @@ + + + + + stock.picking.form.view.inherited + stock.picking + + + + + + + + + + +