diff --git a/mobile_service_shop/README.rst b/mobile_service_shop/README.rst new file mode 100644 index 000000000..94afe0acf --- /dev/null +++ b/mobile_service_shop/README.rst @@ -0,0 +1,34 @@ +Mobile Service Management +========================= +Module for mobile service shop daily activities + +Configuration +============= +* No additional configurations needed + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developers: Milind Mohan @ Cybrosys, odoo@cybrosys.com + Mohammed Shahil M P @cybrosys, 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 +========== +.. 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/mobile_service_shop/__init__.py b/mobile_service_shop/__init__.py new file mode 100644 index 000000000..52d4e9e57 --- /dev/null +++ b/mobile_service_shop/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Milind Mohan @ Cybrosys, (odoo@cybrosys.com) +# Mohammed Shahil M P @ Cybrosys, (odoo@cybrosys.com) +# 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 AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from . import models +from . import wizard diff --git a/mobile_service_shop/__manifest__.py b/mobile_service_shop/__manifest__.py new file mode 100644 index 000000000..5ea83712e --- /dev/null +++ b/mobile_service_shop/__manifest__.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Milind Mohan @ Cybrosys, (odoo@cybrosys.com) +# Mohammed Shahil M P @ 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': 'Mobile Service Management', + 'version': '14.0.1.0.0', + 'summary': 'Module for managing mobile service shop daily activities.', + 'category': 'Industries', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'depends': ['base', 'stock_account', 'mail', 'product', 'account'], + 'data': ['security/security.xml', + 'security/ir.model.access.csv', + 'views/mobile_service_views.xml', + 'views/product_template.xml', + 'views/terms_and_condition.xml', + 'views/complaint_template.xml', + 'views/complaint_type.xml', + 'views/brand_models.xml', + 'views/brand.xml', + 'wizard/mobile_create_invoice_views.xml', + 'reports/mobile_service_ticket.xml', + 'reports/service_ticket_template.xml', + 'data/mobile_service_data.xml', + 'data/mobile_service_email_template.xml'], + 'images': ['static/description/banner.png'], + 'installable': True, + 'application': True, + 'auto_install': False, + 'license': 'LGPL-3', +} \ No newline at end of file diff --git a/mobile_service_shop/data/mobile_service_data.xml b/mobile_service_shop/data/mobile_service_data.xml new file mode 100644 index 000000000..f4b1fa2b5 --- /dev/null +++ b/mobile_service_shop/data/mobile_service_data.xml @@ -0,0 +1,23 @@ + + + + + + Mobile Service + sale + SERV + TRUE + + + Mobile Service Charge + service + + + + Mobile Service Advance + service + + + + + \ No newline at end of file diff --git a/mobile_service_shop/data/mobile_service_email_template.xml b/mobile_service_shop/data/mobile_service_email_template.xml new file mode 100644 index 000000000..99e7894a4 --- /dev/null +++ b/mobile_service_shop/data/mobile_service_email_template.xml @@ -0,0 +1,24 @@ + + + + + + + Service Status Email + + ${(object.user_id.email |safe} + ${object.person_name.email |safe} + Ref ${object.name or 'n/a' } + + ${object.person_name.lang} + Dear ${object.person_name.name},

+

Your service request for ${object.brand_name.brand_name or 'n/a' } (${object.model_name.mobile_brand_models or 'n/a' }) with reference no ${object.name or 'n/a' } has been processed to ${object.service_state or 'n/a' } stage.

+

If you have any questions, please let us know.

+

Best regards,

]]> +
+
+ +
+ +
\ No newline at end of file diff --git a/mobile_service_shop/doc/RELEASE_NOTES.md b/mobile_service_shop/doc/RELEASE_NOTES.md new file mode 100755 index 000000000..e48c5cf44 --- /dev/null +++ b/mobile_service_shop/doc/RELEASE_NOTES.md @@ -0,0 +1,7 @@ +## Module + +#### 05.10.2020 +#### Version 14.0.1.0.0 +#### ADD + +Initial Commit. \ No newline at end of file diff --git a/mobile_service_shop/models/__init__.py b/mobile_service_shop/models/__init__.py new file mode 100644 index 000000000..be71dbc02 --- /dev/null +++ b/mobile_service_shop/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Milind Mohan @ Cybrosys, (odoo@cybrosys.com) +# Mohammed Shahil M P @ 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 mobile_service +from . import service_ticket +from . import product_order_line +from . import product \ No newline at end of file diff --git a/mobile_service_shop/models/mobile_service.py b/mobile_service_shop/models/mobile_service.py new file mode 100644 index 000000000..6ecca2ef0 --- /dev/null +++ b/mobile_service_shop/models/mobile_service.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Milind Mohan @ Cybrosys, (odoo@cybrosys.com) +# Mohammed Shahil M P @ 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 datetime import datetime, date, timedelta +from odoo import models, fields, api, _ +from odoo.exceptions import Warning, UserError +import pytz + + +class MobileServiceShop(models.Model): + _name = 'mobile.service' + _rec_name = 'name' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string='Service Number', copy=False, default="New") + person_name = fields.Many2one('res.partner', string="Customer Name", required=True) + contact_no = fields.Char(related='person_name.mobile', string="Contact Number") + email_id = fields.Char(related='person_name.email', string="Email") + + street = fields.Char(related='person_name.street', string="Address") + street2 = fields.Char(related='person_name.street2', string="Address") + city = fields.Char(related='person_name.city', string="Address") + state_id = fields.Many2one(related='person_name.state_id', string="Address") + zip = fields.Char(related='person_name.zip', string="Address") + country_id = fields.Many2one(related='person_name.country_id', string="Address") + + brand_name = fields.Many2one('mobile.brand', string="Mobile Brand") + is_in_warranty = fields.Boolean( + 'In Warranty', default=False, + help="Specify if the product is in warranty.") + + warranty_number = fields.Char(string="Warranty No ", help="warranty details") + + re_repair = fields.Boolean( + 'Re-repair', default=False, + help="Re-repairing.") + + imei_no = fields.Char(string="IMEI Number") + + model_name = fields.Many2one('brand.model', string="Model", domain="[('mobile_brand_name','=',brand_name)]") + image_medium = fields.Binary(related='model_name.image_medium', store=True, attachment=True) + date_request = fields.Date(string="Requested date", default=fields.Date.context_today) + return_date = fields.Date(string="Return date", required=True) + technician_name = fields.Many2one('res.users', string="Technician Name", + default=lambda self: self.env.user, required=True) + service_state = fields.Selection([('draft', 'Draft'), ('assigned', 'Assigned'), + ('completed', 'Completed'), ('returned', 'Returned'), + ('not_solved', 'Not solved')], + string='Service Status', default='draft', track_visibility='always') + + complaints_tree = fields.One2many('mobile.complaint.tree', 'complaint_id', string='Complaints Tree') + + product_order_line = fields.One2many('product.order.line', 'product_order_id', string='Parts Order Lines') + + internal_notes = fields.Text(string="Internal notes") + invoice_count = fields.Integer(compute='_invoice_count', string='# Invoice', copy=False) + invoice_ids = fields.Many2many("account.move", string='Invoices', compute="_get_invoiced", readonly=True, + copy=False) + + first_payment_inv = fields.Many2one('account.move', copy=False) + + first_invoice_created = fields.Boolean(string="First Invoice Created", invisible=True, copy=False) + + journal_type = fields.Many2one('account.journal', 'Journal', invisible=True, + default=lambda self: self.env['account.journal'].search([('code', '=', 'SERV')])) + + company_id = fields.Many2one('res.company', 'Company', + default=lambda self: self.env['res.company']._company_default_get('mobile.service')) + + @api.model + def _default_picking_transfer(self): + type_obj = self.env['stock.picking.type'] + company_id = self.env.context.get('company_id') or self.env.user.company_id.id + types = type_obj.search([('code', '=', 'outgoing'), ('warehouse_id.company_id', '=', company_id)], limit=1) + if not types: + types = type_obj.search([('code', '=', 'outgoing'), ('warehouse_id', '=', False)]) + return types[:4] + + stock_picking_id = fields.Many2one('stock.picking', string="Picking Id") + + picking_transfer_id = fields.Many2one('stock.picking.type', 'Deliver To', required=True, + default=_default_picking_transfer, + help="This will determine picking type of outgoing shipment") + + picking_count = fields.Integer() + + @api.onchange('return_date') + def check_date(self): + if self.return_date != False: + return_date_string = datetime.strptime(str(self.return_date), "%Y-%m-%d") + request_date_string = datetime.strptime(str(self.date_request), "%Y-%m-%d") + if return_date_string < request_date_string: + raise UserError("Return date should be greater than requested date") + + def approve(self): + self.service_state = 'assigned' + + def complete(self): + self.service_state = 'completed' + + def return_to(self): + self.service_state = 'returned' + + def not_solved(self): + self.service_state = 'not_solved' + + def action_send_mail(self): + ''' + This function opens a window to compose an email, with the edi sale template message loaded by default + ''' + self.ensure_one() + ir_model_data = self.env['ir.model.data'] + try: + template_id = ir_model_data.get_object_reference('mobile_service_shop', 'email_template_mobile_service')[1] + except ValueError: + template_id = False + try: + compose_form_id = ir_model_data.get_object_reference('mail', 'email_compose_message_wizard_form')[1] + except ValueError: + compose_form_id = False + ctx = { + 'default_model': 'mobile.service', + 'default_res_id': self.ids[0], + 'default_use_template': bool(template_id), + 'default_template_id': template_id, + 'default_composition_mode': 'comment', + } + return { + 'name': _('Compose Email'), + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'mail.compose.message', + 'views': [(compose_form_id, 'form')], + 'view_id': compose_form_id, + 'target': 'new', + 'context': ctx, + } + + def return_advance(self): + inv_obj = self.env['account.move'].search([('invoice_origin', '=', self.name)]) + inv_ids = [] + for each in inv_obj: + inv_ids.append(each.id) + view_id = self.env.ref('account.view_move_form').id + if inv_ids: + if len(inv_ids) <= 1: + value = { + 'view_mode': 'form', + 'res_model': 'account.move', + 'view_id': view_id, + 'type': 'ir.actions.act_window', + 'name': 'Invoice', + 'res_id': inv_ids and inv_ids[0] + } + else: + value = { + 'domain': str([('id', 'in', inv_ids)]), + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'view_id': False, + 'type': 'ir.actions.act_window', + 'name': 'Invoice', + 'res_id': inv_ids + } + + return value + else: + raise UserError("No invoice created") + + def _invoice_count(self): + invoice_ids = self.env['account.move'].search([('invoice_origin', '=', self.name)]) + self.invoice_count = len(invoice_ids) + + @api.model + def create(self, vals): + print(self.env.user.company_id) + if 'company_id' in vals: + vals['name'] = self.env['ir.sequence'].with_context(force_company=self.env.user.company_id.id).next_by_code( + 'mobile.service') or _('New') + else: + vals['name'] = self.env['ir.sequence'].next_by_code('mobile.service') or _('New') + vals['service_state'] = 'draft' + return super(MobileServiceShop, self).create(vals) + + def unlink(self): + for i in self: + if i.service_state != 'draft': + raise UserError(_('You cannot delete an assigned service request')) + return super(MobileServiceShop, self).unlink() + + def action_invoice_create_wizard(self): + + return { + 'name': _('Create Invoice'), + 'view_mode': 'form', + 'res_model': 'mobile.invoice', + 'type': 'ir.actions.act_window', + 'target': 'new' + } + + def action_post_stock(self): + flag = 0 + for order in self.product_order_line: + if order.product_uom_qty > order.qty_stock_move: + flag = 1 + pick = { + 'picking_type_id': self.picking_transfer_id.id, + 'partner_id': self.person_name.id, + 'origin': self.name, + 'location_dest_id': self.person_name.property_stock_customer.id, + 'location_id': self.picking_transfer_id.default_location_src_id.id, + } + + picking = self.env['stock.picking'].create(pick) + self.stock_picking_id = picking.id + self.picking_count = len(picking) + moves = order.filtered( + lambda r: r.product_id.type in ['product', 'consu'])._create_stock_moves_transfer(picking) + move_ids = moves._action_confirm() + move_ids._action_assign() + if order.product_uom_qty < order.qty_stock_move: + raise UserError(_('Used quantity is less than quantity stock move posted. ')) + if flag != 1: + raise UserError(_('Nothing to post stock move')) + if flag != 1: + raise UserError(_('Nothing to post stock move')) + + def action_view_invoice(self): + inv_obj = self.env['account.move'].search([('invoice_origin', '=', self.name)]) + inv_ids = [] + for each in inv_obj: + inv_ids.append(each.id) + view_id = self.env.ref('account.view_move_form').id + ctx = dict( + create=False, + ) + if inv_ids: + if len(inv_ids) <= 1: + value = { + 'view_mode': 'form', + 'res_model': 'account.move', + 'view_id': view_id, + 'type': 'ir.actions.act_window', + 'name': 'Invoice', + 'context': ctx, + 'res_id': inv_ids and inv_ids[0] + } + else: + value = { + 'domain': str([('id', 'in', inv_ids)]), + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'view_id': False, + 'type': 'ir.actions.act_window', + 'context': ctx, + 'name': 'Invoice', + 'res_id': inv_ids + } + + return value + + def get_ticket(self): + self.ensure_one() + user = self.env['res.users'].browse(self.env.uid) + if user.tz: + tz = pytz.timezone(user.tz) + time = pytz.utc.localize(datetime.now()).astimezone(tz) + date_today = time.strftime("%Y-%m-%d %H:%M %p") + else: + date_today = datetime.strftime(datetime.now(), "%Y-%m-%d %I:%M:%S %p") + complaint_text = "" + description_text = "" + complaint_id = self.env['mobile.complaint.tree'].search([('complaint_id', '=', self.id)]) + if complaint_id: + for obj in complaint_id: + complaint = obj.complaint_type_tree + description = obj.description_tree + complaint_text = complaint.complaint_type + ", " + complaint_text + if description.description: + description_text = description.description + ", " + description_text + else: + for obj in complaint_id: + complaint = obj.complaint_type_tree + complaint_text = complaint.complaint_type + ", " + complaint_text + data = { + 'ids': self.ids, + 'model': self._name, + 'date_today': date_today, + 'date_request': self.date_request, + 'date_return': self.return_date, + 'sev_id': self.name, + 'warranty': self.is_in_warranty, + 'customer_name': self.person_name.name, + 'imei_no': self.imei_no, + 'technician': self.technician_name.name, + 'complaint_types': complaint_text, + 'complaint_description': description_text, + 'mobile_brand': self.brand_name.brand_name, + 'model_name': self.model_name.mobile_brand_models, + + } + return self.env.ref('mobile_service_shop.mobile_service_ticket').report_action(self, data=data) + + +class MobileBrand(models.Model): + _name = 'mobile.brand' + _rec_name = 'brand_name' + + brand_name = fields.Char(string="Mobile Brand", required=True) + + +class MobileComplaintType(models.Model): + _name = 'mobile.complaint' + _rec_name = 'complaint_type' + + complaint_type = fields.Char(string="Complaint Type", required=True) + + +class MobileComplaintTypeTemplate(models.Model): + _name = 'mobile.complaint.description' + _rec_name = 'description' + + complaint_type_template = fields.Many2one('mobile.complaint', string="Complaint Type Template", required=True) + description = fields.Text(string="Complaint Description") + + +class MobileComplaintTree(models.Model): + _name = 'mobile.complaint.tree' + _rec_name = 'complaint_type_tree' + + complaint_id = fields.Many2one('mobile.service') + + complaint_type_tree = fields.Many2one('mobile.complaint', string="Category", required=True) + description_tree = fields.Many2one('mobile.complaint.description', string="Description", + domain="[('complaint_type_template','=',complaint_type_tree)]") + + +class MobileBrandModels(models.Model): + _name = 'brand.model' + _rec_name = 'mobile_brand_models' + + mobile_brand_name = fields.Many2one('mobile.brand', string="Mobile Brand", required=True) + mobile_brand_models = fields.Char(string="Model Name", required=True) + image_medium = fields.Binary(string='image', store=True, attachment=True) + + +class MobileServiceTermsAndConditions(models.Model): + _name = 'terms.conditions' + _rec_name = 'terms_id' + + terms_id = fields.Char(String="Terms and condition", compute="_find_id") + terms_conditions = fields.Text(string="Terms and Conditions") + + def _find_id(self): + self.terms_id = self.id or '' + + diff --git a/mobile_service_shop/models/product.py b/mobile_service_shop/models/product.py new file mode 100644 index 000000000..ca57029fe --- /dev/null +++ b/mobile_service_shop/models/product.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Milind Mohan @ Cybrosys, (odoo@cybrosys.com) +# Mohammed Shahil M P @ 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 ProductProduct(models.Model): + _inherit = 'product.template' + + is_a_parts = fields.Boolean( + 'Is a Mobile Part', default=False, + help="Specify if the product is a mobile part or not.") + + brand_name = fields.Many2one('mobile.brand', String="Brand", help="Select a mobile brand for the part") + model_name = fields.Many2one('brand.model', String="Model Name", domain="[('mobile_brand_name','=',brand_name)]", + help="Select a model for the part") + model_colour = fields.Char(string="Colour", help="colour for the part") + extra_descriptions = fields.Text(string="Note") \ No newline at end of file diff --git a/mobile_service_shop/models/product_order_line.py b/mobile_service_shop/models/product_order_line.py new file mode 100644 index 000000000..33be7d3f5 --- /dev/null +++ b/mobile_service_shop/models/product_order_line.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Milind Mohan @ Cybrosys, (odoo@cybrosys.com) +# Mohammed Shahil M P @ 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 ProductOrderLine(models.Model): + + _name = 'product.order.line' + + product_order_id = fields.Many2one('mobile.service') + + product_id = fields.Many2one('product.product', string='Product', + domain="[('is_a_parts','=', True)]", required=True) + product_uom_qty = fields.Float(string='Used Quantity', default=1.0, required=True) + price_unit = fields.Float(string='Unit Price', default=0.0, required=True) + qty_invoiced = fields.Float(string='Invoiced qty', readonly=True) + qty_stock_move = fields.Float(string='Stock Move Posted Qty', readonly=True) + part_price = fields.Char(compute='_compute_amount', string='Price', readonly=True, store=True) + product_uom = fields.Char(string='Unit of Measure', required=True) + + @api.onchange('product_id') + def change_prod(self): + self.ensure_one() + if self.product_id: + product_template_obj = self.product_id.product_tmpl_id + self.price_unit = product_template_obj.list_price + self.product_uom = product_template_obj.uom_id.name + + @api.depends('product_uom_qty', 'product_id') + def _compute_amount(self): + """ + Compute the amount + """ + for line in self: + price = line.price_unit * line.product_uom_qty + + line.update({ + 'part_price': price, + }) + + def _create_stock_moves_transfer(self, picking): + moves = self.env['stock.move'] + done = self.env['stock.move'].browse() + if self.product_id.product_tmpl_id.type != 'service': + price_unit = self.price_unit + template = { + 'name': self.product_id.product_tmpl_id.name or '', + 'product_id': self.product_id.id, + 'product_uom': self.product_id.product_tmpl_id.uom_id.id, + 'location_id': picking.picking_type_id.default_location_src_id.id, + 'location_dest_id': self.product_order_id.person_name.property_stock_customer.id, + 'picking_id': picking.id, + 'move_dest_ids': False, + 'state': 'draft', + 'company_id': self.product_order_id.company_id.id, + 'price_unit': price_unit, + 'picking_type_id': picking.picking_type_id.id, + 'route_ids': 1 and [ + (6, 0, [x.id for x in self.env['stock.location.route'].search([('id', 'in', (2, 3))])])] or [], + 'warehouse_id': picking.picking_type_id.warehouse_id.id, + } + qty = self.product_uom_qty - self.qty_stock_move + print(qty) + diff_quantity = qty + tmp = template.copy() + tmp.update({ + 'product_uom_qty': diff_quantity, + }) + template['product_uom_qty'] = diff_quantity + done += moves.create(template) + self.qty_stock_move = self.qty_stock_move + qty + return done \ No newline at end of file diff --git a/mobile_service_shop/models/service_ticket.py b/mobile_service_shop/models/service_ticket.py new file mode 100755 index 000000000..cb224f9eb --- /dev/null +++ b/mobile_service_shop/models/service_ticket.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Milind Mohan @ Cybrosys, (odoo@cybrosys.com) +# Mohammed Shahil M P @ 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, api + + +class StockMoveReport(models.AbstractModel): + + _name = 'report.mobile_service_shop.mobile_service_ticket_template' + + @api.model + def _get_report_values(self, docids, data): + terms = self.env['terms.conditions'].search([]) + return { + 'date_today': data['date_today'], + 'date_request': data['date_request'], + 'date_return': data['date_return'], + 'sev_id': data['sev_id'], + 'imei_no': data['imei_no'], + 'technician': data['technician'], + 'complaint_types': data['complaint_types'], + 'complaint_description': data['complaint_description'], + 'mobile_brand': data['mobile_brand'], + 'model_name': data['model_name'], + 'customer_name': data['customer_name'], + 'warranty': data['warranty'], + 'terms': terms, + } diff --git a/mobile_service_shop/reports/mobile_service_ticket.xml b/mobile_service_shop/reports/mobile_service_ticket.xml new file mode 100644 index 000000000..5a9f0cc4d --- /dev/null +++ b/mobile_service_shop/reports/mobile_service_ticket.xml @@ -0,0 +1,12 @@ + + + + + Mobile Service Ticket + mobile.service + qweb-pdf + mobile_service_shop.mobile_service_ticket_template + mobile_service_shop.mobile_service_ticket_template + + + \ No newline at end of file diff --git a/mobile_service_shop/reports/service_ticket_template.xml b/mobile_service_shop/reports/service_ticket_template.xml new file mode 100644 index 000000000..484091d2f --- /dev/null +++ b/mobile_service_shop/reports/service_ticket_template.xml @@ -0,0 +1,83 @@ + + + + + \ No newline at end of file diff --git a/mobile_service_shop/security/ir.model.access.csv b/mobile_service_shop/security/ir.model.access.csv new file mode 100644 index 000000000..ca693432e --- /dev/null +++ b/mobile_service_shop/security/ir.model.access.csv @@ -0,0 +1,15 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_mobile_service_shop_mobile_service_shop,access.mobile_service_shop.mobile_service_shop,model_mobile_service,mobile_service_group_executer,1,1,0,0 +access_mobile_service_shop_mobile_service_shop11,access.mobile_service_shop.mobile_service_shop11,model_mobile_complaint,mobile_service_group_executer,1,0,0,0 +access_mobile_service_shop_mobile_service_shop22,access.mobile_service_shop.mobile_service_shop22,model_mobile_service,mobile_service_group_manager,1,1,1,1 +access_mobile_service_shop_mobile_service_shop33,access.mobile_service_shop.mobile_service_shop33,model_mobile_brand,mobile_service_group_manager,1,1,1,1 +access_mobile_service_shop_mobile_service_shop44,access.mobile_service_shop.mobile_service_shop44,model_brand_model,mobile_service_group_manager,1,1,1,1 +access_mobile_service_shop_mobile_service_shop66,access.mobile_service_shop.mobile_service_shop66,model_mobile_complaint,mobile_service_group_manager,1,1,1,1 +access_mobile_service_shop_mobile_service_shop88,access.mobile_service_shop.mobile_service_shop88,model_product_template,mobile_service_group_manager,1,1,1,1 +access_mobile_service_shop_mobile_service_shop99,access.mobile_service_shop.mobile_service_shop99,model_mobile_complaint_tree,mobile_service_group_executer,1,1,1,0 +access_mobile_service_shop_mobile_service_shop111,access.mobile_service_shop.mobile_service_shop111,model_mobile_complaint_description,mobile_service_group_manager,1,1,1,1 +access_mobile_service_shop_mobile_service_shop112,access.mobile_service_shop.mobile_service_shop112,model_terms_conditions,mobile_service_group_manager,1,1,1,1 +access_mobile_service_shop_mobile_service_shop113,access.mobile_service_shop.mobile_service_shop113,model_mobile_complaint_tree,mobile_service_group_manager,1,1,1,1 +access_mobile_service_shop_mobile_service_shop114,access.mobile_service_shop.mobile_service_shop114,model_mobile_complaint_description,mobile_service_group_executer,1,1,0,0 +access_mobile_service_shop_mobile_service_shop115,access.mobile_service_shop.mobile_service_shop115,model_product_order_line,mobile_service_group_executer,1,1,1,1 +access_mobile_service_shop_mobile_service_shop116,access.mobile_service_shop.mobile_service_shop116,model_mobile_invoice,mobile_service_group_manager,1,1,1,1 diff --git a/mobile_service_shop/security/security.xml b/mobile_service_shop/security/security.xml new file mode 100644 index 000000000..c52e40263 --- /dev/null +++ b/mobile_service_shop/security/security.xml @@ -0,0 +1,36 @@ + + + + + Mobile Service + 5 + + + + Mobile Technician + + + + + + Manager + + + + + + + Mobile Service rule + + [('technician_name','=',user.id),('service_state','!=','draft'), ('company_id','=',user.company_id.id)] + + + + + Mobile Service Manager rule + + [('company_id','=',user.company_id.id)] + + + + \ No newline at end of file diff --git a/mobile_service_shop/static/description/banner.png b/mobile_service_shop/static/description/banner.png new file mode 100644 index 000000000..5174338fc Binary files /dev/null and b/mobile_service_shop/static/description/banner.png differ diff --git a/mobile_service_shop/static/description/icon.png b/mobile_service_shop/static/description/icon.png new file mode 100644 index 000000000..933c80c27 Binary files /dev/null and b/mobile_service_shop/static/description/icon.png differ diff --git a/mobile_service_shop/static/description/images/Brand.png b/mobile_service_shop/static/description/images/Brand.png new file mode 100644 index 000000000..77c1c6c85 Binary files /dev/null and b/mobile_service_shop/static/description/images/Brand.png differ diff --git a/mobile_service_shop/static/description/images/a1.png b/mobile_service_shop/static/description/images/a1.png new file mode 100644 index 000000000..a4e213557 Binary files /dev/null and b/mobile_service_shop/static/description/images/a1.png differ diff --git a/mobile_service_shop/static/description/images/a2.png b/mobile_service_shop/static/description/images/a2.png new file mode 100644 index 000000000..e9841afe8 Binary files /dev/null and b/mobile_service_shop/static/description/images/a2.png differ diff --git a/mobile_service_shop/static/description/images/advanced_stock.png b/mobile_service_shop/static/description/images/advanced_stock.png new file mode 100644 index 000000000..6156b14bf Binary files /dev/null and b/mobile_service_shop/static/description/images/advanced_stock.png differ diff --git a/mobile_service_shop/static/description/images/all service rq.png b/mobile_service_shop/static/description/images/all service rq.png new file mode 100644 index 000000000..469ee94d3 Binary files /dev/null and b/mobile_service_shop/static/description/images/all service rq.png differ diff --git a/mobile_service_shop/static/description/images/banner.png b/mobile_service_shop/static/description/images/banner.png new file mode 100644 index 000000000..0950f6f7e Binary files /dev/null and b/mobile_service_shop/static/description/images/banner.png differ diff --git a/mobile_service_shop/static/description/images/barcode_scanning.jpeg b/mobile_service_shop/static/description/images/barcode_scanning.jpeg new file mode 100644 index 000000000..529143e4e Binary files /dev/null and b/mobile_service_shop/static/description/images/barcode_scanning.jpeg differ diff --git a/mobile_service_shop/static/description/images/checked.png b/mobile_service_shop/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/mobile_service_shop/static/description/images/checked.png differ diff --git a/mobile_service_shop/static/description/images/complaint templates.png b/mobile_service_shop/static/description/images/complaint templates.png new file mode 100644 index 000000000..b278e8f5d Binary files /dev/null and b/mobile_service_shop/static/description/images/complaint templates.png differ diff --git a/mobile_service_shop/static/description/images/complaint types.png b/mobile_service_shop/static/description/images/complaint types.png new file mode 100644 index 000000000..2faeca8d8 Binary files /dev/null and b/mobile_service_shop/static/description/images/complaint types.png differ diff --git a/mobile_service_shop/static/description/images/cybrosys.png b/mobile_service_shop/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/mobile_service_shop/static/description/images/cybrosys.png differ diff --git a/mobile_service_shop/static/description/images/email.png b/mobile_service_shop/static/description/images/email.png new file mode 100644 index 000000000..e954257fd Binary files /dev/null and b/mobile_service_shop/static/description/images/email.png differ diff --git a/mobile_service_shop/static/description/images/export.jpeg b/mobile_service_shop/static/description/images/export.jpeg new file mode 100644 index 000000000..5dfdf2c2b Binary files /dev/null and b/mobile_service_shop/static/description/images/export.jpeg differ diff --git a/mobile_service_shop/static/description/images/inventory_valuation.png b/mobile_service_shop/static/description/images/inventory_valuation.png new file mode 100644 index 000000000..02df9a68b Binary files /dev/null and b/mobile_service_shop/static/description/images/inventory_valuation.png differ diff --git a/mobile_service_shop/static/description/images/invoice line.png b/mobile_service_shop/static/description/images/invoice line.png new file mode 100644 index 000000000..74bdf9b92 Binary files /dev/null and b/mobile_service_shop/static/description/images/invoice line.png differ diff --git a/mobile_service_shop/static/description/images/invoice.png b/mobile_service_shop/static/description/images/invoice.png new file mode 100644 index 000000000..13107ee2a Binary files /dev/null and b/mobile_service_shop/static/description/images/invoice.png differ diff --git a/mobile_service_shop/static/description/images/invoice_payment.png b/mobile_service_shop/static/description/images/invoice_payment.png new file mode 100644 index 000000000..560c3a123 Binary files /dev/null and b/mobile_service_shop/static/description/images/invoice_payment.png differ diff --git a/mobile_service_shop/static/description/images/l1.png b/mobile_service_shop/static/description/images/l1.png new file mode 100644 index 000000000..ab30eb4ef Binary files /dev/null and b/mobile_service_shop/static/description/images/l1.png differ diff --git a/mobile_service_shop/static/description/images/mobile.png b/mobile_service_shop/static/description/images/mobile.png new file mode 100644 index 000000000..032640c0f Binary files /dev/null and b/mobile_service_shop/static/description/images/mobile.png differ diff --git a/mobile_service_shop/static/description/images/models.png b/mobile_service_shop/static/description/images/models.png new file mode 100644 index 000000000..417ea27ea Binary files /dev/null and b/mobile_service_shop/static/description/images/models.png differ diff --git a/mobile_service_shop/static/description/images/new service rq.png b/mobile_service_shop/static/description/images/new service rq.png new file mode 100644 index 000000000..23a105fab Binary files /dev/null and b/mobile_service_shop/static/description/images/new service rq.png differ diff --git a/mobile_service_shop/static/description/images/o1.png b/mobile_service_shop/static/description/images/o1.png new file mode 100644 index 000000000..2c8263fdd Binary files /dev/null and b/mobile_service_shop/static/description/images/o1.png differ diff --git a/mobile_service_shop/static/description/images/o2.png b/mobile_service_shop/static/description/images/o2.png new file mode 100644 index 000000000..627653155 Binary files /dev/null and b/mobile_service_shop/static/description/images/o2.png differ diff --git a/mobile_service_shop/static/description/images/o3.png b/mobile_service_shop/static/description/images/o3.png new file mode 100644 index 000000000..aed7896c5 Binary files /dev/null and b/mobile_service_shop/static/description/images/o3.png differ diff --git a/mobile_service_shop/static/description/images/parts.png b/mobile_service_shop/static/description/images/parts.png new file mode 100644 index 000000000..91fb01252 Binary files /dev/null and b/mobile_service_shop/static/description/images/parts.png differ diff --git a/mobile_service_shop/static/description/images/post stock moves.png b/mobile_service_shop/static/description/images/post stock moves.png new file mode 100644 index 000000000..c20cd8e85 Binary files /dev/null and b/mobile_service_shop/static/description/images/post stock moves.png differ diff --git a/mobile_service_shop/static/description/images/print tkt.png b/mobile_service_shop/static/description/images/print tkt.png new file mode 100644 index 000000000..3fa818856 Binary files /dev/null and b/mobile_service_shop/static/description/images/print tkt.png differ diff --git a/mobile_service_shop/static/description/images/product part.png b/mobile_service_shop/static/description/images/product part.png new file mode 100644 index 000000000..3a3ef780c Binary files /dev/null and b/mobile_service_shop/static/description/images/product part.png differ diff --git a/mobile_service_shop/static/description/images/product_barcode.png b/mobile_service_shop/static/description/images/product_barcode.png new file mode 100644 index 000000000..683ba5b0d Binary files /dev/null and b/mobile_service_shop/static/description/images/product_barcode.png differ diff --git a/mobile_service_shop/static/description/images/s1.png b/mobile_service_shop/static/description/images/s1.png new file mode 100644 index 000000000..d5683332e Binary files /dev/null and b/mobile_service_shop/static/description/images/s1.png differ diff --git a/mobile_service_shop/static/description/images/s2.png b/mobile_service_shop/static/description/images/s2.png new file mode 100644 index 000000000..da0bf30a7 Binary files /dev/null and b/mobile_service_shop/static/description/images/s2.png differ diff --git a/mobile_service_shop/static/description/images/service request.png b/mobile_service_shop/static/description/images/service request.png new file mode 100644 index 000000000..a4096f049 Binary files /dev/null and b/mobile_service_shop/static/description/images/service request.png differ diff --git a/mobile_service_shop/static/description/images/service ticket.png b/mobile_service_shop/static/description/images/service ticket.png new file mode 100644 index 000000000..7d5ca2f11 Binary files /dev/null and b/mobile_service_shop/static/description/images/service ticket.png differ diff --git a/mobile_service_shop/static/description/images/stock_ageing.jpeg b/mobile_service_shop/static/description/images/stock_ageing.jpeg new file mode 100644 index 000000000..92effb57b Binary files /dev/null and b/mobile_service_shop/static/description/images/stock_ageing.jpeg differ diff --git a/mobile_service_shop/static/description/images/task_timer_youtube.png b/mobile_service_shop/static/description/images/task_timer_youtube.png new file mode 100644 index 000000000..fb6579727 Binary files /dev/null and b/mobile_service_shop/static/description/images/task_timer_youtube.png differ diff --git a/mobile_service_shop/static/description/images/terms&conditions.png b/mobile_service_shop/static/description/images/terms&conditions.png new file mode 100644 index 000000000..eabd6ee18 Binary files /dev/null and b/mobile_service_shop/static/description/images/terms&conditions.png differ diff --git a/mobile_service_shop/static/description/index.html b/mobile_service_shop/static/description/index.html new file mode 100644 index 000000000..58fd8900a --- /dev/null +++ b/mobile_service_shop/static/description/index.html @@ -0,0 +1,468 @@ +
cybrosys-logo
+
+
+
+

Mobile Service Management

+

This module helps in managing mobile service shop daily activities.

+
+

Key Highlights

+
    + +
  • Service request creation.
  • +
  • Assigning service request to technicians.
  • +
  • Mobile service ticket generation.
  • +
  • Tracking the service status.
  • +
  • Integrated with accounting and sales module.
  • +
  • Multi-level access rights.
  • +
  • Mobile complaint templates.
  • +
  • Invoice for parts usage and service charges.
  • +
  • Email notifications to customer.
  • +
  • Parts inventory.
  • +
  • Flexible for further customization.
  • + +
+
+
+
+
+
+
+
+ +
+
+ +

Overview

+
+

+ TThis module is exclusively designed for the mobile service shop for managing their daily activities inside the service center. The module comes integrated with accounting and inventory modules maximizing the efficiency. It comes embedded with features such as adding complaint templates, making it a much user-friendly application. The module also helps in generating service tickets in the workplace. +

+
+ + + + + +
+ + +

Access Rights

+
+
    +

    + Manager :- Manager has the complete access over the mobile shop management.

    +

    +

    + Mobile Technician :- Mobile Technician can read and write service requests and also update the parts usage. +

    +
+
+
+ +

Mobile Service Management

+
+
    +

    + Service request creation. +

    +

    + Assigning service request to technicians. +

    +

    + Mobile service ticket generation. +

    +

    + Tracking the service status. +

    +

    + Integrated with accounting and sales module. +

    +

    + Multi-level access rights +

    +

    + Mobile complaint templates. +

    +

    + Invoice for parts usage and service charges. +

    +

    + Email notifications to customer. +

    +

    + Parts inventory. +

    +

    + Flexible for further customization. +

    +
+
+ +
+
+

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/mobile_service_shop/views/brand.xml b/mobile_service_shop/views/brand.xml new file mode 100644 index 000000000..0c1792256 --- /dev/null +++ b/mobile_service_shop/views/brand.xml @@ -0,0 +1,45 @@ + + + + + mobile.brand.form + mobile.brand + +
+ + + + + + + +
+
+
+ + + mobile.brand.tree + mobile.brand + + + + + + + + + Brand + mobile.brand + tree,form + + +

+ Click to Create a New Record. +

+
+
+ + +
+
\ No newline at end of file diff --git a/mobile_service_shop/views/brand_models.xml b/mobile_service_shop/views/brand_models.xml new file mode 100644 index 000000000..59ece8bf5 --- /dev/null +++ b/mobile_service_shop/views/brand_models.xml @@ -0,0 +1,82 @@ + + + + + mobile.brand.model.form + brand.model + +
+ + + + + + + + + +
+
+
+ + + mobile.service.kanban + brand.model + + + + + + + +
+
+ Product +
+
+ + + +
+
+
    +
  • model:
  • +
+
+
+ + + + + + + + + mobile.brand.model.tree + brand.model + + + + + + + + + + + + Models + brand.model + kanban,tree,form + +

+ Click to Create a New Record. +

+
+
+ + + + \ No newline at end of file diff --git a/mobile_service_shop/views/complaint_template.xml b/mobile_service_shop/views/complaint_template.xml new file mode 100644 index 000000000..22a5383b7 --- /dev/null +++ b/mobile_service_shop/views/complaint_template.xml @@ -0,0 +1,45 @@ + + + + + mobile.complaint.template.form + mobile.complaint.description + +
+ + + + + + +
+
+
+ + + mobile.complaint.type.tree + mobile.complaint.description + + + + + + + + + + Complaint Types + mobile.complaint.description + tree,form + + +

+ Click to Create a New Record. +

+
+
+ + +
+
\ No newline at end of file diff --git a/mobile_service_shop/views/complaint_type.xml b/mobile_service_shop/views/complaint_type.xml new file mode 100644 index 000000000..1a3815bf1 --- /dev/null +++ b/mobile_service_shop/views/complaint_type.xml @@ -0,0 +1,47 @@ + + + + + mobile.complaint.type.form + mobile.complaint + +
+ + + + + + + +
+
+
+ + + mobile.complaint.type.tree + mobile.complaint + + + + + + + + + Complaint Types + mobile.complaint + tree,form + + +

+ Click to Create a New Record. +

+
+ +
+ + +
+
\ No newline at end of file diff --git a/mobile_service_shop/views/mobile_service_views.xml b/mobile_service_shop/views/mobile_service_views.xml new file mode 100644 index 000000000..6fa6e07bf --- /dev/null +++ b/mobile_service_shop/views/mobile_service_views.xml @@ -0,0 +1,307 @@ + + + + + + Service Code + mobile.service + SERV/ + + + + + + + service.request.search1 + mobile.service + + + + + + + + + + + + + + + + + + + + + + + + mobile.service.request.form + mobile.service + +
+
+
+ +
+ +
+
+

+ +

+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+
+ + +
+ +
+
+ + + mobile.service.kanban + mobile.service + + + + + + +
+
+ +
+
+
+ + + +
+
+ +
+ +
+
+
+
+
+
+
+
+
+ + + mobile.service.graph + mobile.service + + + + + + + + + mobile.service.request.tree + mobile.service + + + + + + + + + + + + + + + + + + Service Request + mobile.service + tree,form,kanban,pivot,graph + + + +

+ Click to Create a New Record. +

+
+
+ + + + + + + + + + + +
+
\ No newline at end of file diff --git a/mobile_service_shop/views/product_template.xml b/mobile_service_shop/views/product_template.xml new file mode 100644 index 000000000..84ffe0010 --- /dev/null +++ b/mobile_service_shop/views/product_template.xml @@ -0,0 +1,68 @@ + + + + + + product.parts.form.view + product.template + + + + + + + + + + + + + + + + + + + + + + + + + + product.template.product.kanban + product.template + + + + + + + + + + + + + + Products + ir.actions.act_window + product.product + kanban,tree,form + {"search_default_consumable":1, 'default_type': 'product'} + [('is_a_parts', '=', True)] + +

+ Click to define a new product. +

+
+
+ + + + +
+
\ No newline at end of file diff --git a/mobile_service_shop/views/terms_and_condition.xml b/mobile_service_shop/views/terms_and_condition.xml new file mode 100644 index 000000000..59c42d9b4 --- /dev/null +++ b/mobile_service_shop/views/terms_and_condition.xml @@ -0,0 +1,44 @@ + + + + + mobile.terms.and.conditions.form + terms.conditions + +
+ + + + + +
+
+
+ + + mobile.terms.and.conditions.tree + terms.conditions + + + + + + + + + Terms and Conditions + terms.conditions + tree,form + + +

+ Click to Create a New Record. +

+
+
+ + +
+
\ No newline at end of file diff --git a/mobile_service_shop/wizard/__init__.py b/mobile_service_shop/wizard/__init__.py new file mode 100644 index 000000000..b42d7c3d2 --- /dev/null +++ b/mobile_service_shop/wizard/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Milind Mohan @ Cybrosys, (odoo@cybrosys.com) +# Mohammed Shahil M P @ 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 mobile_create_invoice + diff --git a/mobile_service_shop/wizard/mobile_create_invoice.py b/mobile_service_shop/wizard/mobile_create_invoice.py new file mode 100644 index 000000000..faa87e611 --- /dev/null +++ b/mobile_service_shop/wizard/mobile_create_invoice.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Milind Mohan @ Cybrosys, (odoo@cybrosys.com) +# Mohammed Shahil M P @ 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, fields, models, _ +from odoo.exceptions import Warning, UserError +from odoo.exceptions import UserError, ValidationError + + +class MobileServiceInvoice(models.Model): + + _name = 'mobile.invoice' + + advance_payment_method = fields.Selection([('advance', 'Advance'), ('full_amount', 'Full amount')], + string='Invoice method', default='advance') + amount = fields.Integer(string='Amount') + number = fields.Char(string='Service Id') + + def action_invoice_create(self): + active_id = self._context.get('active_id') + service_id = self.env['mobile.service'].search([('id', '=', active_id)]) + if not service_id.env['product.product'].search([("name", "=", "Mobile Service Advance")]): + vals = self._prepare_advance_product() + self.env['product.product'].create(vals) + + if not service_id.env['product.product'].search([("name", "=", "Mobile Service Charge")]): + vals1 = self._prepare_service_product() + self.env['product.product'].create(vals1) + + service_id.first_invoice_created = True + inv_obj = self.env['account.move'] + inv_line_obj = self.env['account.move.line'] + supplier = service_id.person_name + inv_data = { + 'move_type': 'out_invoice', + 'ref': supplier.name, + 'partner_id': supplier.id, + 'currency_id': service_id.company_id.currency_id.id, + 'journal_id': service_id.journal_type.id, + 'invoice_origin': service_id.name, + 'company_id': service_id.company_id.id, + } + inv_id = inv_obj.create(inv_data) + service_id.first_payment_inv = inv_id.id + self.number = service_id.name + if self.advance_payment_method != 'advance': + product_id = service_id.env['product.product'].search([("name", "=", "Mobile Service Charge")]) + else: + product_id = service_id.env['product.product'].search([("name", "=", "Mobile Service Advance")]) + + if product_id.property_account_income_id.id: + income_account = product_id.property_account_income_id.id + elif product_id.categ_id.property_account_income_categ_id.id: + income_account = product_id.categ_id.property_account_income_categ_id.id + else: + raise UserError('Please define income account for this product: "%s" (id:%d).' % + (product_id.name, product_id.id)) + flag = 0 + if self.amount: + flag = 1 + inv_line_data = [(0, 0, { + 'name': product_id.name, + 'price_unit': self.amount, + 'quantity': 1, + 'credit': self.amount, + 'debit': 0, + 'account_id': income_account, + 'product_id': product_id.id, + 'move_id': inv_id.id, + })] + inv_id.write({ + 'invoice_line_ids': inv_line_data}) + inv_id._recompute_payment_terms_lines() + + sale_order_product = self.env['product.order.line'].search([('product_order_id', '=', service_id.name)]) + for line_data in sale_order_product: + qty = line_data.product_uom_qty - line_data.qty_invoiced + if line_data.product_uom_qty < line_data.qty_invoiced: + raise UserError(_('Used quantity is less than invoiced quantity')) + uom_id = line_data.product_id.product_tmpl_id.uom_id + if qty > 0: + flag = 1 + price = line_data.product_id.list_price + inv_line_data = [(0, 0, { + 'name': line_data.product_id.name, + 'price_unit': price, + 'quantity': qty, + 'product_uom_id': uom_id.id, + 'credit': price, + 'debit': 0, + 'account_id': income_account, + 'product_id': line_data.product_id.id, + 'move_id': inv_id.id, + })] + inv_id.write({ + 'invoice_line_ids': inv_line_data}) + line_data.qty_invoiced = line_data.qty_invoiced + qty + inv_id._recompute_payment_terms_lines() + + inv_id.post() + if flag != 1: + raise UserError(_('Nothing to create invoice')) + imd = service_id.env['ir.model.data'] + action = imd.xmlid_to_object('account.action_move_out_invoice_type') + list_view_id = imd.xmlid_to_res_id('account.view_move_tree') + form_view_id = imd.xmlid_to_res_id('account.view_move_form') + result = { + 'name': action.name, + 'help': action.help, + 'type': 'ir.actions.act_window', + 'views': [[list_view_id, 'tree'], [form_view_id, 'form'], [False, 'graph'], [False, 'kanban'], + [False, 'calendar'], [False, 'pivot']], + 'target': action.target, + 'context': action.context, + 'res_model': 'account.move', + } + if len(inv_id) > 1: + result['domain'] = "[('id','in',%s)]" % inv_id.ids + elif len(inv_id) == 1: + result['views'] = [(form_view_id, 'form')] + result['res_id'] = inv_id.ids[0] + else: + result = {'type': 'ir.actions.act_window_close'} + return result + + def _prepare_advance_product(self): + return { + 'name': 'Mobile Service Advance', + 'type': 'service', + 'invoice_policy': 'order', + 'company_id': False, + } + + def _prepare_service_product(self): + return { + 'name': 'Mobile Service Charge', + 'type': 'service', + 'invoice_policy': 'order', + 'company_id': False, + } diff --git a/mobile_service_shop/wizard/mobile_create_invoice_views.xml b/mobile_service_shop/wizard/mobile_create_invoice_views.xml new file mode 100644 index 000000000..23b033929 --- /dev/null +++ b/mobile_service_shop/wizard/mobile_create_invoice_views.xml @@ -0,0 +1,38 @@ + + + Create Invoice + mobile.invoice + +
+

+ Invoices will be created in draft so that you can review + them before validation. +

+ + + +
+
+
+
+
+ + + + Create Invoice + ir.actions.act_window + mobile.invoice + form + new + + + +