from email.policy import default import re from odoo import fields, models, api import time import datetime from datetime import datetime, timedelta from odoo.tools import config from odoo.addons import decimal_precision as dp from odoo.tools.translate import _ # from dateutil import relativedelta import calendar from odoo import exceptions, _ # from odoo.exceptions import except_orm, UserError from odoo.exceptions import UserError from dateutil.relativedelta import relativedelta from dateutil.parser import * import pytz import math import logging _logger = logging.getLogger(__name__) # @api.multi def get_price(self, pricelist_ids, price): price_amt = 0.0 pricelist_item_ids = [] if self._context is None: self._context = {} date = time.strftime('%Y-%m-%d') if 'date' in self._context: date = self._context['date'] currency_obj = self.env['res.currency'] product_pricelist_version_obj = self.env['product.pricelist.item'] user_browse = self.env['res.users'].browse() company_obj = self.env['res.company'] company_id = company_obj.browse(user_browse.company_id.id) # print company_id.currency_id.id ,"company_idccccc" pricelist_obj = self.env['product.pricelist'].browse(pricelist_ids) if pricelist_ids: pricelist_item_ids.append(pricelist_ids) pricelist_obj = self.env['product.pricelist'].browse(pricelist_ids) pricelist_item_ids = list(set(pricelist_item_ids)) plversions_search_args = [ ('pricelist_id', 'in', pricelist_item_ids), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ] plversion_ids = product_pricelist_version_obj.search( plversions_search_args) if not plversion_ids: msg = "At least one pricelist item has not declared !\nPlease create pricelist item." # raise osv.except_osv(_('Warning !'), _(msg)) raise exceptions.except_orm(_('Warning !'), _(msg)) self._cr.execute( 'SELECT i.* ' 'FROM product_pricelist_item AS i ' 'WHERE id = ' + str(plversion_ids[0].id) + '') res1 = self._cr.dictfetchall() if pricelist_obj: price = currency_obj.compute(price, pricelist_obj.currency_id, round) for res in res1: if res: price_limit = price x = (1.0 + (res['price_discount'] or 0.0)) price = price * (1.0 + (res['price_discount'] or 0.0)) price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit + res['price_min_margin']) if res['price_max_margin']: price = min(price, price_limit + res['price_max_margin']) break price_amt = price return price_amt class CrmLead2OpportunityPartner(models.TransientModel): _inherit = 'crm.lead2opportunity.partner' _description = 'Lead To Opportunity Partner' @api.model_create_multi def create(self, vals): for rec in vals: rec.update({'lead_id': self._context.get('active_id')}) res = super(CrmLead2OpportunityPartner, self).create(vals) return res @api.model def default_get(self, fields): """ Default get for name, opportunity_ids. If there is an exisitng partner link to the lead, find all existing opportunities links with this partner to merge all information together """ res = {} if 'action' in fields: res.update({'action': 'create'}) if 'name' in fields: res.update({'name': 'convert'}) result = super(CrmLead2OpportunityPartner, self).default_get(fields) if not result.get('lead_id') and self.env.context.get('active_id'): result['lead_id'] = self.env.context.get('active_id') return res # @api.multi # @api.model def action_apply(self): """ Convert lead to opportunity or merge lead and opportunity and open the freshly created opportunity view. """ ctx = dict(self._context) if 'banquet_id' in self._context: banq_browse = self.env['banquet.quotation'].browse( self._context['banquet_id']) ctx['active_id'] = banq_browse.lead.id ctx['active_ids'] = [banq_browse.lead.id] # self._context.update({'active_id' :banq_browse.lead.id,'active_ids':[banq_browse.lead.id]}) # lead = self.env['crm.lead'].browse(self._context.get('active_ids'))[0] lead = self.env['crm.lead'].search([('id', '=', ctx['active_id'])]) # lead_ids = self._context.get('active_ids', []) lead_ids = ctx['active_ids'] if lead: lead.convert_opportunity(self.partner_id.id) res = super(CrmLead2OpportunityPartner, self).action_apply() # return lead.redirect_lead_opportunity_view() return res class CrmLead(models.Model): _name = 'crm.lead' _inherit = 'crm.lead' _description = 'User Modification' via = fields.Selection( [('direct', 'Direct'), ('agent', 'Agent')], 'Via', default=lambda *a: 'direct') agent_id = fields.Many2one('res.partner', 'Agent') lead_sequence = fields.Char('Lead Number', readonly=True) banquets_ids = fields.One2many( 'banquet.quotation.lead.history', 'ref_id', 'Banquet Quotation History') shop_id = fields.Many2one('sale.shop', 'Hotel', required=True, help="Will show only open leads for the selected shop.") # @api.multi def name_get(self): if not len(self._ids): return [] res = [(r['id'], r['lead_sequence']) for r in self.read(fields=['lead_sequence'])] return res @api.model_create_multi def create(self, vals): # function overwrites create method and auto generate request no. req_no = self.env['ir.sequence'].next_by_code('crm.lead') or 'New' for rec in vals: rec['lead_sequence'] = req_no return super(CrmLead, self).create(vals) # @api.one def unlink(self): """ Allows to delete lead which are created once """ for rec in self.browse(): raise exceptions.except_orm( _('Invalid action !'), _('Cannot delete these Lead.!')) return super(CrmLead, self).unlink() @api.onchange('shop_id') def on_change_shop_id(self): if not self.shop_id: return {'value': {}} temp = self.env['sale.shop'].browse(self.shop_id.id) return {'value': {'company_id': temp.company_id.id}} class DepositPaymentPolicy(models.Model): _name = "deposit.payment.policy" _description = "Deposit Payment Policy" start_date = fields.Date("From Date", required=True) name = fields.Char('Policy Name', required=True) percentage = fields.Float("Percentage", required=True) min_amount = fields.Float("Minimum Deposit Amount", required=True) shop_id = fields.Many2one('sale.shop', 'Hotel', required=True, help="Will show list of shop that belongs to allowed companies of logged-in user. \n -Assign a shop to configure shop-wise deposit policy.") company_id = fields.Many2one( related='shop_id.company_id', string='Company', store=True) # _sql_constraints = [ # ('policy_name_uniq', 'unique(name,shop_id)', # 'Policy Name must be unique for selected shop !'), # ('start_date_uniq', 'unique(start_date,shop_id)', # 'Start Date must be unique for selected shop !') # ] class ThemePlan(models.Model): _name = "theme.plan" _description = "Theme Plan" name = fields.Char('Theme Name', required=True) code = fields.Char('Code', ) # _sql_constraints = [ # ('theme_name_uniq', 'unique(name)', 'Theme Name must be unique !'), # ] class SeatingPlan(models.Model): _name = "seating.plan" _description = "Seating Plan" name = fields.Char('Name', required=True) code = fields.Char('Code') # _sql_constraints = [ # ('theme_name_uniq', 'unique(name)', 'Seating Name must be unique !'), # ] class BanquetQuotation(models.Model): _name = "banquet.quotation" _description = "Banquet Quotation" # @api.one def unlink(self): """ Allows to delete Product Category which are not defined in demo data """ for rec in self.browse(): raise exceptions.except_orm(_('Invalid action !'), _( 'Cannot delete these Quotation.!')) # raise osv.except_osv(_('Invalid action !'), _('Cannot delete these Quotation.!')) return super(BanquetQuotation, self).unlink() @api.onchange('pricelist_id') @api.depends('room_ids', 'food_items_ids', 'other_items_ids') def onchange_pricelist_id(self): if not self.pricelist_id: return {} temp = 0 if self.pricelist_id: if not self.room_ids == [(6, 0, [])] and len(self.room_ids) != 1: temp = 1 if not self.food_items_ids == [(6, 0, [])] and len(self.food_items_ids) != 1: temp = 1 if not self.other_items_ids == [(6, 0, [])] and len(self.other_items_ids) != 1: temp = 1 if temp == 0: return {} # warning = { # 'title': _('Pricelist Warning!'), # 'message': _('If you change the pricelist of this order (and eventually the currency), prices of existing order lines will not be updated.') # } @api.model_create_multi def create(self, vals): # function overwrites create method and auto generate request no. req_no = self.env['ir.sequence'].next_by_code( 'banquet.quotation') or 'New' for rec in vals: rec['name'] = req_no lead_browse = self.env['crm.lead'].browse(rec['lead']) if (not lead_browse.email_from) and 'email_id' in rec and rec['email_id']: lead_browse.write({'email_from': rec['email_id']}) if (not lead_browse.mobile) and 'mobile' in rec and rec['mobile']: lead_browse.write({'mobile': rec['mobile']}) if (not lead_browse.contact_name) and 'contact_name' in rec and rec['contact_name']: lead_browse.write({'contact_name': rec['contact_name']}) return super(BanquetQuotation, self).create(vals) def _get_total_amt_pur(self): res = {} for obj in self: obj.pur_total_amt = obj.pur_untax_amt + obj.pur_tax_amt # @api.multi def _amount_line_tax_pur(self, line): val = 0.0 taxes = line.pur_tax_ids.compute_all( line.cost_price_unit * (1 - (line.discount or 0.0) / 100.0), line.currency_id, 1) val = taxes['total_included'] - taxes['total_excluded'] return val # @api.multi def _amount_line_tax_pur_food_other(self, line): val = 0.0 user_id = self.env['res.users'].search([('id', '=', self._context.get('uid'))]) taxes = line.pur_tax_ids.compute_all( line.cost_price_unit * (1 - (line.discount or 0.0) / 100.0), user_id.company_id.currency_id, 1) val = taxes['total_included'] - taxes['total_excluded'] return val def _get_tax_amt_pur(self): res = {} total = 0.00 val = 0.00 cur_obj = self.env['res.currency'] res_user = self.env['res.users'] for obj in self: user_id = res_user.browse() cur = user_id.company_id.currency_id for line in obj.room_ids: val += self._amount_line_tax_pur(line) for line in obj.food_items_ids: val += self._amount_line_tax_pur_food_other(line) for line in obj.other_items_ids: val += self._amount_line_tax_pur_food_other(line) # res[obj.id] = cur_obj.round(val) obj.update({ 'pur_tax_amt': val, }) # return res def _get_untax_amt_pur(self): res = {} total = 0.00 for obj in self: for service in obj.room_ids: total += service.cost_price_subtotal for food in obj.food_items_ids: total += food.cost_price_subtotal for other in obj.other_items_ids: total += other.cost_price_subtotal # res[obj.id] = total obj.pur_untax_amt = total # return res def _get_total_amt_sale(self): res = {} for obj in self: obj.sale_total_amt = obj.sale_untax_amt + obj.sale_tax_amt # return res # @api.multi def _amount_line_tax(self, line): val = 0.0 line.company_id = self.env['res.users'].search([('id', '=', self._context.get('uid'))]).company_id line.currency_id = line.company_id.currency_id taxes = line.taxes_id.compute_all( line.price * (1 - (line.discount or 0.0) / 100.0), line.currency_id, line.number_of_days) val = taxes['total_included'] - taxes['total_excluded'] return val # @api.multi def _amount_food_tax(self, line): val = 0.0 taxes = line.tax_id.compute_all( line.price_subtotal * (1 - (line.discount or 0.0) / 100.0), None, 1) val = taxes['total_included'] - taxes['total_excluded'] return val # @api.multi def _amount_other_tax(self, line): val = 0.0 taxes = line.tax_id.compute_all( line.price_subtotal * (1 - (line.discount or 0.0) / 100.0), None, 1) val = taxes['total_included'] - taxes['total_excluded'] return val def _get_tax_amt_sale(self): res = {} val = 0.00 cur_obj = self.env['res.currency'] res_user = self.env['res.users'] for obj in self: user_id = res_user.browse() cur = user_id.company_id.currency_id for line in obj.room_ids: val += self._amount_line_tax(line) for line in obj.food_items_ids: val += self._amount_food_tax(line) for line in obj.other_items_ids: val += self._amount_other_tax(line) # res[obj.id] = cur_obj.round(val) obj.update({ 'sale_tax_amt': val, }) # return res def _get_untax_amt_sale(self): res = {} total = 0.00 for obj in self: for service in obj.room_ids: total += service.sub_total1 for food in obj.food_items_ids: total += food.price_subtotal for other in obj.other_items_ids: total += other.price_subtotal obj.update({ 'sale_untax_amt': total, }) # res[obj.id] = total # return res # @api.multi @api.depends('room_ids') def count_total_rooms(self): res = {} for obj in self: count1 = 0 for line in obj.room_ids: count1 += 1 self.number_of_rooms = count1 def count_total_days(self): current_date = datetime.today().date() date_object = (self.checkout, '%Y-%m-%d %H:%M:%S') if current_date != date_object: if self.in_date >= self.out_date: checkout = self.in_date checkout += timedelta(days=1) self.out_date = checkout ch_in = self.in_date ch_out = self.out_date check_in = self.in_date check_out = self.out_date day_count1 = (check_out - check_in).days if day_count1 == 0: day_count1 = 1 day_count1 = round(day_count1) self.number_of_days = day_count1 @api.model def _get_default_shop(self): user = self.env['res.users'].browse(self._uid) company_id = user.company_id.id shop_ids = self.env['sale.shop'].search( [('company_id', '=', company_id)]) if not shop_ids: raise exceptions.except_orm(_('Error!'), _( 'There is no default shop for the current user\'s company!')) return shop_ids[0] @api.onchange('shop_id') def onchange_shop_id(self): v = {} if self.shop_id: shop = self.env['sale.shop'].browse(self.shop_id.id) if shop.pricelist_id: v['pricelist_id'] = shop.pricelist_id.id return {'value': v} name = fields.Char("Quotation No.", readonly=True) current_date = fields.Date("Enquiry Date", required=True, readonly=True, default=time.strftime('%Y-%m-%d')) lead = fields.Many2one('crm.lead', 'Lead', required=True, readonly=True) contact_name = fields.Char('Contact Name', readonly=True) address = fields.Char('Address', readonly=True) email_id = fields.Char('Email Id', readonly=True) # 'tour_name':fields.char('Banquet Name', readonly=True, states={'draft': [('readonly', False)]},), mobile = fields.Char('Mobile Number', required=True, readonly=True) adult = fields.Integer("Adult Persons", readonly=True) child = fields.Integer("Child", readonly=True) in_date = fields.Datetime("Prefer Start Date") out_date = fields.Datetime("Prefer End Date") via = fields.Selection([('direct', 'Direct'), ('agent', 'Agent')], "Via", readonly=True, default='direct') agent_id = fields.Many2one('res.partner', 'Agent', readonly=True) room_ids = fields.One2many('hotel.reservation.line', 'banquet_id', 'Room Details', readonly=True) food_items_ids = fields.One2many('food.items', 'banquet_id', 'Food Items') other_items_ids = fields.One2many( 'other.items', 'banquet_id', 'Other Items') number_of_days = fields.Integer(compute='count_total_days', string="Number Of Days", default=1, help="Shall be computed based on check out policy configured for selected shop.") number_of_rooms = fields.Integer( compute='count_total_rooms', string="Number Of Rooms") state = fields.Selection([ ('draft', 'Draft'), ('confirm', 'Confirm'), ('send_to', 'Sent To Customer'), ('approve', 'Approved'), # ('create_tour', 'Create Banquet Booking'), ('done', 'Done'), ('refused', 'Refused'), ], 'Status', default='draft') # ,readonly=True), theme_id = fields.Many2one('theme.plan', 'Theme', required=True, readonly=True) board_toread = fields.Char("Board to Read", readonly=True) seating_id = fields.Many2one('seating.plan', 'Seating Plan', required=True, readonly=True) sale_untax_amt = fields.Float( compute='_get_untax_amt_sale', string="Sale Untaxed Amount") sale_tax_amt = fields.Float( compute='_get_tax_amt_sale', string="Sale Taxes ") pur_untax_amt = fields.Float( compute='_get_untax_amt_pur', string="Purchase Untaxed Amount") pur_tax_amt = fields.Float( compute='_get_tax_amt_pur', string="Purchase Taxes ") sale_total_amt = fields.Float( compute='_get_total_amt_sale', string="Sale Total Amount") pur_total_amt = fields.Float( compute='_get_total_amt_pur', string="Purchase Total Amount") deposit_policy = fields.Selection([('percentage', 'Deposit Percentage'), ('no_deposit', 'No Deposit')], 'Deposit Policy', required=True, readonly=True, default='no_deposit') percentage = fields.Float("Percentage/Deposit Amount", readonly=True) min_dep_amount = fields.Float("Minimum Deposit Amount", readonly=True) invoiced = fields.Boolean('Invoiced', default=False) pricelist_id = fields.Many2one('product.pricelist', 'Pricelist', required=True, readonly=True) shop_id = fields.Many2one('sale.shop', 'Hotel', domain="[('company_id', '=', [current_company_id])]", required=True, readonly=True, default=_get_default_shop, help="Will show list of shop that belongs to allowed companies of logged-in user.") company_id = fields.Many2one( related='shop_id.company_id', string='Company', store=True) # _sql_constraints = [ # ('check_in_out_dates', 'CHECK (checkin_date<=checkout_date)', # 'Prefer start Date Should be lesser than the Prefer End Date!'), # ] @api.onchange('lead') def on_change_lead_id(self): result = {} if self.lead: res = self.env['crm.lead'].browse(self.lead.id) address = '' if res.street: address += res.street + ' ' if res.street2: address += res.street2 + ' ' if res.city: address += res.city + ' ' if res.zip: address += res.zip result['address'] = address result['contact_name'] = res.contact_name result['mobile'] = res.mobile result['email_id'] = res.email_from result['via'] = res.via result['agent_id'] = res.agent_id.id return {'value': result} @api.onchange('shop_id', 'in_date', 'out_date') def on_change_checkout(self): # self.checkin_date =time.strftime('%Y-%m-%d %H:%M:%S') # self.checkout_date=time.strftime('%Y-%m-%d %H:%M:%S') val = {} if not self.shop_id: raise UserError('Shop is not selected.') if not self.out_date: self.out_date = time.strftime('%Y-%m-%d %H:%M:%S') if self.in_date and self.shop_id.id: new_date = str(self.in_date) self._cr.execute( 'select max(start_date) from deposit_payment_policy where start_date <= %s and shop_id = %s', (new_date, self.shop_id.id,)) a = self._cr.fetchone() # if not a[0]: # raise UserError('Deposit policy is not define.') # raise exceptions.except_orm('Configuration Error', 'Deposit policy is not define.') pay_obj = self.env['deposit.payment.policy'].search( [('start_date', '=', a[0])]) val = {'value': { 'percentage': pay_obj.percentage, 'min_dep_amount': pay_obj.min_amount}} return val def compute(self): res = {} total = 0.00 val = 0.00 pur_total = 0.00 pur_val = 0.00 user_id = self.env['res.users'].search([('id', '=', self._context.get('uid'))]) cur_obj = user_id.company_id.currency_id res_user = self.env['res.users'] for obj in self: user_id = res_user.browse() cur = user_id.company_id.currency_id for line in obj.room_ids: line.sub_total1 = line.price total += line.sub_total1 val += self._amount_line_tax(line) pur_total += line.cost_price_subtotal pur_val += self._amount_line_tax_pur(line) for line in obj.food_items_ids: total += line.price_subtotal val += self._amount_food_tax(line) pur_total += line.cost_price_subtotal pur_val += self._amount_line_tax_pur_food_other(line) for line in obj.other_items_ids: total += line.price_subtotal val += self._amount_other_tax(line) pur_total += line.cost_price_subtotal pur_val += self._amount_line_tax_pur_food_other(line) res[obj.id] = cur_obj.round(val) sum = total + val pur_sum = pur_total + pur_val self.write({'sale_tax_amt': val, 'sale_total_amt': sum, 'sale_untax_amt': total, 'pur_tax_amt': pur_val, 'pur_total_amt': pur_sum, 'pur_untax_amt': pur_total }) return True def action_confirm(self): for obj in self: if not obj.room_ids: raise exceptions.except_orm( _("Warning"), _("Room Details are missing.")) for room in obj.room_ids: room_line_id = self.env['hotel.room'].search( [('product_id', '=', room.room_number.id)]) room_line_browse = self.env['hotel.room'].browse( room_line_id.id) if room_line_browse.room_folio_ids: for history in room_line_browse.room_folio_ids: if history.state == 'done': history_start_date = history.check_in history_end_date = history.check_out reservation_start_date = obj.in_date reservation_end_date = obj.out_date if (history_start_date <= reservation_start_date < history_end_date) or ( history_start_date < reservation_end_date <= history_end_date) or ( (reservation_start_date < history_start_date) and ( reservation_end_date > history_end_date)): if not (obj == history.booking_id): raise exceptions.except_orm(_("Warning"), _( "You tried to confirm reservation with room %s which is already reserved in this reservation period !") % ( room.room_number.name)) self.write({'state': 'confirm'}) return True def action_approve(self): for obj in self: data_obj = self.env['ir.model.data'] data_id = data_obj._xmlid_to_res_id( 'crm.view_crm_lead2opportunity_partner') view_id1 = False if self._context is None: self._context = {} ctx = dict(self._context) ctx['active_ids'] = [obj.id] ctx['banquet_id'] = obj.id if data_id: view_id1 = data_id # value = { # 'name': _('Create Partner'), # 'view_type': 'form', # 'view_mode': 'form', # 'res_model': 'crm.lead2opportunity.partner', # 'view_id': view_id1, # 'context': ctx, # 'views': [(view_id1, 'form')], # 'type': 'ir.actions.act_window', # 'target': 'new', # 'nodestroy': True # } id_lead = self.env['crm.lead'].browse(obj.lead.id) rejected_history_id = self.env['banquet.quotation.lead.history'].search( [('ref_id', '=', id_lead.id)]) if rejected_history_id: for id in rejected_history_id: self.env['banquet.quotation.lead.history'].write( {'state': 'refused', 'update_date': time.strftime('%Y-%m-%d')}) history_id = self.env['banquet.quotation.lead.history'].search( [('name', '=', obj.name), ('ref_id', '=', id_lead.id)]) if history_id: self.env['banquet.quotation.lead.history'].write( {'state': 'approve', 'update_date': time.strftime('%Y-%m-%d')}) rejected_itinary = self.search([('lead', '=', id_lead.id)]) if rejected_itinary: for rec in rejected_itinary: rec.write({'state': 'refused'}) obj.write({'state': 'approve'}) def action_refuse(self): for obj in self: id_lead = self.env['crm.lead'].browse(obj.lead.id) history_id = self.env['banquet.quotation.lead.history'].search( [('name', '=', obj.name), ('ref_id', '=', id_lead.id)]) if history_id: self.env['banquet.quotation.lead.history'].write( {'state': 'refused', 'update_date': time.strftime('%Y-%m-%d')}) obj.write({'state': 'refused'}) return True def action_sent(self): for obj in self: id_lead = self.env['crm.lead'].browse(obj.lead.id) itinarary_id = self.env['banquet.quotation.lead.history'].create({ 'name': obj.name, 'contact_name': obj.contact_name, 'state': 'send_to', 'ref_id': id_lead.id, 'current_date': time.strftime('%Y-%m-%d'), 'update_date': time.strftime('%Y-%m-%d'), }) stage = self.env['crm.stage'].search( [('name', '=', 'Proposition')]) if stage: self.env['crm.lead'].write({'stage_id': stage.id}) obj.write({'state': 'send_to'}) return True def action_create_tour(self): for obj in self: # shop = self.env['sale.shop'].search([]) if not self.shop_id: raise exceptions.except_orm( 'Configuration Error', 'Shop is not define.') shop_id = self.env['sale.shop'].browse(self.shop_id.id) if not obj.lead.partner_id: raise UserError(_( "Please convert the Lead '%s' in Opportunity first!") % (obj.lead.lead_sequence)) banquet_id = self.env['hotel.reservation'].create({ 'shop_id': obj.shop_id.id, 'pricelist_id': obj.pricelist_id.id, 'banq_bool': True, 'partner_id': obj.lead.partner_id.id, 'adults': obj.adult, 'childs': obj.child, 'deposit_policy': obj.deposit_policy, 'percentage': obj.percentage, 'min_dep_amount': obj.min_dep_amount, 'banquet_id': obj.id, 'via': obj.via, 'agent_id': obj.agent_id.id, 'source': 'internal_reservation', }) for room in obj.room_ids: tax_ids = [] for tax_line in room.taxes_id: tax_ids.append(tax_line.id) room_booking_id = self.env['hotel.reservation.line'].create({ 'room_number': room.room_number.id, 'price': room.price, 'categ_id': room.categ_id.id, 'discount': room.discount, 'taxes_id': [(6, 0, tax_ids)], 'line_id': banquet_id.id, 'checkin': obj.in_date, 'checkout': obj.out_date, }) for room in obj.food_items_ids: tax_ids = [] for tax_line in room.tax_id: tax_ids.append(tax_line.id) self.env['food.items'].create({ 'product_id': room.product_id.id, 'name': room.product_id.name, 'price_unit': room.price_unit, 'discount': room.discount, 'tax_id': [(6, 0, tax_ids)], 'food_items_id': banquet_id.id, 'product_uom': room.product_uom.id, 'product_uom_qty': room.product_uom_qty }) for room in obj.other_items_ids: tax_ids = [] for tax_line in room.tax_id: tax_ids.append(tax_line.id) room_booking_id = self.env['other.items'].create({ 'product_id': room.product_id.id, 'name': room.product_id.name, 'price_unit': room.price_unit, 'discount': room.discount, 'tax_id': [(6, 0, tax_ids)], 'other_items_id': banquet_id.id, 'product_uom': room.product_uom.id, 'product_uom_qty': room.product_uom_qty }) tour_search = self.env['hotel.reservation'].search( [('id', '=', banquet_id.id)]) custom_tour = self.env['hotel.reservation'].browse(tour_search.id) obj.write({'state': 'done'}) return True class HotelReservationLine(models.Model): _inherit = "hotel.reservation.line" _description = "Reservation Line" def count_total_days(self): res = {} for obj in self: if obj.company_id.id == self.env.user.company_id.id: policy_obj = self.env['checkout.configuration'].sudo().search([('shop_id', '=', obj.line_id.shop_id.id)]) # if not policy_obj: # raise UserError( # 'Configuration Error! Checkout policy is not define for selected Hotel.') policy_browse = self.env['checkout.configuration'].sudo().browse(policy_obj.id) ch_in = obj.checkin ch_out = obj.checkout check_in = obj.checkin check_out = obj.checkout day_count1 = (check_out - check_in).days if not policy_browse.name == '24hour': check_in = obj.checkin check_out = obj.checkout day_count1 = check_out - check_in day_count2 = day_count1.total_seconds() day_count2 = day_count2 / 86400 day_count2 = "{:.2f}".format(day_count2) day_count2 = math.ceil(float(day_count2)) day_count1 = day_count2 else: day_count1 = check_out - check_in day_count2 = day_count1.total_seconds() day_count2 = day_count2 / 86400 day_count2 = "{:.2f}".format(day_count2) day_count2 = math.ceil(float(day_count2)) day_count1 = day_count2 obj.number_of_days = day_count1 else: obj.number_of_days = 0 # def count_total_days(self): # res = {} # for obj in self: # if obj.company_id.id == self.env.user.company_id.id: # policy_obj = self.env['checkout.configuration'].search( # [('shop_id', '=', obj.line_id.shop_id.id)]) # if not policy_obj: # raise UserError( # 'Configuration Error! Checkout policy is not define for selected Hotel.') # policy_browse = self.env['checkout.configuration'].browse( # policy_obj.id) # ch_in = obj.checkin # ch_out = obj.checkout # check_in = obj.checkin # check_out = obj.checkout # day_count1 = (check_out - check_in).days # if day_count1 == 0: # day_count1 = 1 # # if not policy_browse.name == '24hour': # # wd_count = 0 # # time_con = str(policy_browse.time) # # check_out_cons = obj.checkin # # for count in range(0, (int(day_count1))): # # single_date = check_in + relativedelta(days=count) # # day = calendar.weekday(int(single_date.strftime("%Y")), int( # # single_date.strftime("%m")), int(single_date.strftime("%d"))) # # if str(single_date) == obj.checkin: # # time_con = str(policy_browse.time) # # check_out_cons = obj.checkin # # if obj.checkin < check_out_cons: # # wd_count += 1 # # if obj.checkout > check_out_cons: # # wd_count += 1 # # elif str(single_date) == obj.checkout: # # time_con = str(policy_browse.time) # # check_out_cons = obj.checkout # # if obj.checkout > check_out_cons: # # wd_count += 1 # # if (str(single_date) != obj.checkin) and (str(single_date) != obj.checkout): # # time_con = str(policy_browse.time) # # check_out_cons = obj.checkin # # if obj.checkout > check_out_cons: # # wd_count += 1 # # day_count1 = wd_count # # else: # # day_count = (check_out - check_in).days + 1 # # time_in = obj.checkin # # time_out = obj.checkout # # time_count1 = (time_out - time_in) # # if time_count1 > timedelta(0): # # day_count += 1 # # day_count1 = round(day_count) # obj.update({ # 'number_of_days': day_count1, # }) @api.depends('number_of_days', 'discount', 'price', 'taxes_id', 'room_number') def count_price(self): _logger.info('compute method : 2') tax_obj = self.env['account.tax'] cur_obj = self.env['res.currency'] res_user = self.env['res.users'] res = {} if self._context is None: self._context = {} for line in self: # print('Before tax line : {}'.format(line.sub_total1)) if line.line_id: price = line.price * (1 - (line.discount or 0.0) / 100.0) taxes = line.taxes_id.compute_all( price, None, line.number_of_days) val = taxes['total_excluded'] cur = line.line_id.pricelist_id.currency_id if cur: line.update({ 'sub_total': cur.round(val), }) else: price = line.price * (1 - (line.discount or 0.0) / 100.0) taxes = line.taxes_id.compute_all( price, None, line.number_of_days) val = taxes['total_excluded'] user_id = res_user.browse(self._uid) cur = user_id.company_id.currency_id line.update({ 'sub_total': cur.round(val), }) # print('Before tax line : {}'.format(line.sub_total1)) def _amount_line_cost(self): res_user = self.env['res.users'] res = {} if self._context is None: context = {} for line in self: cur = 0 if line.banquet_id: price = line.cost_price_unit taxes = line.pur_tax_ids.compute_all( price, None, line.number_of_days) val = taxes['total_excluded'] user_id = res_user.browse(self._uid) cur = user_id.company_id.currency_id line.update({ 'cost_price_subtotal': cur.round(val) if cur else 0, }) @api.depends('checkin', 'checkout', 'number_of_days') @api.onchange('room_number') def onchange_room_id(self): if self.line_id: pricelist = self.line_id.pricelist_id.id parent_id = self.line_id if self.banquet_id: pricelist = self.banquet_id.pricelist_id.id parent_id = self.banquet_id room_id = self.room_number v = {} res_list = [] warning = '' if self.banquet_id: if not pricelist: raise exceptions.except_orm( _("Warning"), _("PriceList is not Selected !")) product_browse = room_id ctx = self._context and self._context.copy() or {} ctx.update({'date': self.checkin}) tax_ids = [] for tax_line in product_browse.taxes_id: tax_ids.append(tax_line.id) v['taxes_id'] = [(6, 0, tax_ids)] v['checkin'] = self.checkin v['checkout'] = self.checkout cost_price_unit = get_price( self, pricelist, product_browse.standard_price) v['cost_price_unit'] = cost_price_unit room_line_id = self.env['hotel.room'].search( [('product_id', '=', room_id.id)]) room_line_browse = self.env['hotel.room'].browse(room_line_id.id) if room_line_browse.room_folio_ids: for history in room_line_browse.room_folio_ids: if history.state == 'done': history_start_date = history.check_in history_end_date = history.check_out reservation_start_date = self.checkin reservation_end_date = self.checkout #############################Added by Pornima############ housekeeping_room = self.env['hotel.housekeeping'].search( [('room_no', '=', room_line_browse.product_id.id), ('state', '=', 'dirty')]) if housekeeping_room: for house1 in housekeeping_room: # house = self.env['hotel.housekeeping'].browse(house1.id) house = house1 house_current_date = (datetime.strptime( house.current_date, '%Y-%m-%d')).date() house_end_date = (datetime.strptime( house.end_date, '%Y-%m-%d')).date() start_reser = datetime.strptime( self.checkin, '%Y-%m-%d %H:%M:%S').date() end_reser = datetime.strptime( self.checkout, '%Y-%m-%d %H:%M:%S').date() if (house_current_date <= start_reser <= house_end_date) or ( house_current_date <= end_reser <= house_end_date) or ( (start_reser < house_current_date) and (end_reser > house_end_date)): # if (((start_reser < house_current_date) # and (end_reser > house_end_date)) or # (house_current_date <= start_reser < # house_end_date) or (house_current_date < # end_reser <= house_end_date)) and # (house.state == 'dirty'): raise exceptions.except_orm(_("Warning"), _("Room %s is not clean for reservation period !") % ( room_line_browse[0].name)) #############################Added by Pornima########## if (history_start_date <= reservation_start_date < history_end_date) or ( history_start_date < reservation_end_date <= history_end_date) or ( (reservation_start_date < history_start_date) and ( reservation_end_date > history_end_date)): if not (parent_id == history.booking_id.id): raise exceptions.except_orm(_("Warning"), _( "Room %s is booked in this reservation period !") % (room_line_browse[0].name)) else: if self.line_id: if not self.line_id.pricelist_id: raise UserError("PriceList is not Selected !") if self.room_number: product_browse = self.room_number product_id = product_browse.id price = product_browse.lst_price if price is False: raise UserError( "Couldn't find a pricelist line matching this product!1") ctx = self._context and self._context.copy() or {} ctx.update({'date': self.checkin}) price = self.env['product.pricelist'].with_context(ctx)._price_get( room_id, self.number_of_days)[pricelist] # price = self.env['product.pricelist'].with_context(ctx)._price_get( # room_id.id, self.number_of_days, { # 'uom': product_browse.uom_id.id, # 'date': self.checkin, # })[pricelist] v['price'] = price tax_ids = [] for tax_line in product_browse.taxes_id: tax_ids.append(tax_line.id) v['taxes_id'] = [(6, 0, tax_ids)] v['checkin'] = self.checkin v['checkout'] = self.checkout room_line_id = self.env['hotel.room'].search( [('product_id', '=', product_id)]) housekeeping_room = self.env['hotel.housekeeping'].search( [('room_no', '=', room_line_id.id), ('state', '=', 'dirty')]) if housekeeping_room: for house1 in housekeeping_room: # house = self.env['hotel.housekeeping'].browse(house1) house = house1 house_current_date = (datetime.strptime( str(house.current_date), '%Y-%m-%d')).date() house_end_date = (datetime.strptime( str(house.end_date), '%Y-%m-%d')).date() start_reser = datetime.strptime( str(self.checkin), '%Y-%m-%d %H:%M:%S').date() end_reser = datetime.strptime( str(self.checkout), '%Y-%m-%d %H:%M:%S').date() if (house_current_date <= start_reser <= house_end_date) or ( house_current_date <= end_reser <= house_end_date) or ( (start_reser < house_current_date) and (end_reser > house_end_date)): raise UserError( "Room %s is not clean for reservation period !" % (room_line_id.name)) ################################################################### if room_line_id.room_folio_ids: for history in room_line_id.room_folio_ids: if history.state == 'done': history_start_date = history.check_in history_end_date = history.check_out reservation_start_date = self.checkin reservation_end_date = self.checkout if (history_start_date <= reservation_start_date < history_end_date) or ( history_start_date < reservation_end_date <= history_end_date) or ( (reservation_start_date < history_start_date) and ( reservation_end_date > history_end_date)): if not (self.line_id.id == history.booking_id.id): raise UserError( "Room %s is booked in this reservation period !" % (room_line_id.name,)) return {'value': v, 'warning': warning} currency_id = fields.Many2one( 'res.currency', store=True, string='Currency', readonly=True) banquet_id = fields.Many2one('banquet.quotation', 'Banquet Id') sub_total = fields.Float(compute='count_price', compute_sudo=False, string="sub total") cost_price_unit = fields.Float('Cost Price', digits='Cost Price') cost_price_subtotal = fields.Float( compute='_amount_line_cost', string='Cost Subtotal', digits='Cost Price') pur_tax_ids = fields.Many2many( 'account.tax', 'pur_hotel_line_tax_rel', 'hotel_line_id', 'tax_id', 'Purchase Taxes') purches_bol = fields.Boolean('Show Purchase Tax') number_of_days = fields.Integer( compute='count_total_days', string="Number Of Days", default=1) class HotelReservation(models.Model): _inherit = "hotel.reservation" _description = "Reservation" @api.onchange('deposit_policy') def onchange_deposit_policy(self): v = {} if self.deposit_policy == 'no_deposit': v['percentage'] = 0.0 return {'value': v} @api.depends('reservation_line.price', 'reservation_line.discount') def _get_subtotal_amount(self): line_subtotal = super(HotelReservation, self)._get_subtotal_amount() total = 0.00 tax_obj = self.env['account.tax'] for obj in self: if obj.id: cur = obj.pricelist_id.currency_id for line in obj.reservation_line: price = line.price * (1 - (line.discount or 0.0) / 100.0) taxes = line.taxes_id.compute_all( price, None, line.number_of_days) cur = line.line_id.pricelist_id.currency_id total += line.sub_total1 for food in obj.food_items_ids: total += food.price_subtotal for other in obj.other_items_ids: total += other.price_subtotal obj.update({ 'untaxed_amt': obj.pricelist_id.currency_id.round(total), }) else: obj.update({ 'untaxed_amt': 0, }) @api.depends('reservation_line.price', 'reservation_line.discount') def _get_total_tax(self): res = {} total = 0.00 val = 0.00 total_val = 0.00 tax_obj = self.env['account.tax'] cur_obj = self.env['res.currency'] for obj in self: if obj.id: cur = obj.pricelist_id.currency_id for line in obj.reservation_line: val += self._amount_line_tax(line) for line in obj.food_items_ids: total += line.price_subtotal val += self._amount_food_tax(line) for line in obj.other_items_ids: total += line.price_subtotal val += self._amount_other_tax(line) obj.update({ 'total_tax': cur.round(val), }) else: obj.update({ 'total_tax': 0, }) def _amount_other_tax(self, line): val = 0.0 taxes = line.tax_id.compute_all( line.price_subtotal * (1 - (line.discount or 0.0) / 100.0), line.currency_id, 1) val = taxes['total_included'] - taxes['total_excluded'] return val def _amount_food_tax(self, line): val = 0.0 taxes = line.tax_id.compute_all( line.price_subtotal * (1 - (line.discount or 0.0) / 100.0), line.currency_id, 1) val = taxes['total_included'] - taxes['total_excluded'] return val # @api.multi def _get_total_rental_cost(self): # total amount after deduction by tax res = {} total = 0.00 val = 0.00 sum = 0.00 cur_obj = self.env['res.currency'] for obj in self: total = 0.00 val = 0.00 sum = 0.00 cur = obj.pricelist_id.currency_id for line in obj.reservation_line: total += line.sub_total1 val += self._amount_line_tax(line) for line in obj.food_items_ids: total += line.price_subtotal val += self._amount_food_tax(line) for line in obj.other_items_ids: total += line.price_subtotal val += self._amount_other_tax(line) if cur: sum = cur.round(total) + cur.round(val) # obj.update({ # 'total_cost1': sum, # }) obj.total_cost1 = sum def _get_deposit_cost1(self): total = 0 for obj in self: if obj.deposit_policy == 'percentage': for rental_line in obj.reservation_line: room_line_id = self.env['hotel.room'].search( [('product_id', '=', rental_line.room_number.id)]) if room_line_id: room_line_browse = self.env['hotel.room'].browse(room_line_id)[ 0].id if room_line_id.deposit_bool: total += (rental_line.sub_total1 + self._amount_line_tax( rental_line)) * obj.percentage / 100 if total and (total < obj.min_dep_amount): total = obj.min_dep_amount elif obj.deposit_policy == 'no_deposit': total = 0.0 # obj.update({ # 'deposit_cost': total, # }) obj.deposit_cost = total # @api.onchange('checkout_date') @api.depends('checkin_date') def on_change_checkout(self): self.checkin_date = time.strftime('%Y-%m-%d %H:%M:%S') self.checkout_date = time.strftime('%Y-%m-%d %H:%M:%S') delta = timedelta(days=1) if not self.checkout_date: self.checkout_date = time.strftime('%Y-%m-%d %H:%M:%S') addDays = datetime.datetime( *time.strptime(self.checkout_date, '%Y-%m-%d %H:%M:%S')[:5]) + delta if self.checkin_date: new_date = str(self.checkin_date) self._cr.execute( 'select max(start_date) from deposit_payment_policy where start_date <= %s ', (new_date,)) a = self._cr.fetchone() if not a[0]: raise exceptions.except_orm( 'Configuration Error', 'Deposit policy is not define.') pay_obj = self.env['deposit.payment.policy'].search( [('start_date', '=', a[0])]) dep_obj = self.env['deposit.payment.policy'].browse(pay_obj[0]) val = {'value': {'dummy': addDays.strftime( '%Y-%m-%d %H:%M:%S'), 'percentage': dep_obj.percentage, 'min_dep_amount': dep_obj.min_amount}} return val banq_bool = fields.Boolean('Banquet Booking', default=False) deposit_policy = fields.Selection([('percentage', 'Deposit Percentage'), ('no_deposit', 'No Deposit')], 'Deposit Policy', required=True, readonly=True, default='no_deposit') percentage = fields.Float("Percentage/Deposit Amount") min_dep_amount = fields.Float("Minimum Deposit Amount") deposit_recv_acc = fields.Many2one('account.account', string="Deposit Account", required=False, company_dependent=True) food_items_ids = fields.One2many( 'food.items', 'food_items_id', 'Food Items') other_items_ids = fields.One2many( 'other.items', 'other_items_id', 'Other Items') untaxed_amt = fields.Float( compute='_get_subtotal_amount', string="Untaxed Amount") total_tax = fields.Float(compute='_get_total_tax', type="float", string="Reservation Tax",store=True, help="The amount without tax.") total_cost1 = fields.Float( compute='_get_total_rental_cost', string="Total Reservation cost", ) deposit_cost = fields.Float( compute='_get_deposit_cost1', string="Deposit Cost", ) banquet_id = fields.Many2one( 'banquet.quotation', 'Booking Ref.', readonly=True) agent_comm = fields.Float("Commision") # @api.multi @api.onchange('deposit_policy') def onchange_deposit_policy(self): if self.deposit_policy == 'percentage': self.deposit_recv_acc = self.partner_id.property_account_receivable_id # @api.multi def done(self): active_id = self._ids for reservation in self: booking_ids = self.env['hotel.room.booking.history'].search([('booking_id', '=', reservation.id)]) _logger.info("BOOKING ID===>>>>>>>>>>>>>>>{}".format(booking_ids)) for booking_id in booking_ids: _logger.info("BOOKING ID===>>>>>>>>>>>>>{}".format(booking_id)) _logger.info("datetime now==>>>>>>>>>>{}".format(datetime.now())) booking_id.write({ 'check_in': datetime.now() }) self.write({'agent_comm': reservation.total_cost1, }) if reservation.deposit_cost2: data_obj = self.env['ir.model.data'] data_id = data_obj._get_id( 'hotel_management', 'deposit_journal_entry_wizard1') view_id1 = False if self._context is None: self._context = {} ctx = dict(self._context) ctx['active_ids'] = [reservation.id] ctx['booking_id'] = reservation.id if data_id: view_id1 = data_obj.browse(data_id).res_id value = { 'name': _('Advance Payment Entry'), 'view_type': 'form', 'view_mode': 'form', 'res_model': 'deposit_journal_entry.wizard1', 'view_id': False, 'context': ctx, 'views': [(view_id1, 'form')], 'type': 'ir.actions.act_window', 'target': 'new', 'nodestroy': True } return value elif (reservation.banq_bool and reservation.deposit_cost2): data_obj = self.env['ir.model.data'] data_id = data_obj._get_id( 'banquet_managment', 'deposit_journal_entry_wizard') view_id1 = False if self._context is None: self._context = {} ctx = dict(self._context) ctx['active_ids'] = [reservation.id] ctx['booking_id'] = reservation.id if data_id: view_id1 = data_obj.browse(data_id).res_id value = { 'name': _('Deposit amount entry'), 'view_type': 'form', 'view_mode': 'form', 'res_model': 'deposit_journal_entry.wizard', 'view_id': False, 'context': ctx, 'views': [(view_id1, 'form')], 'type': 'ir.actions.act_window', 'target': 'new', 'nodestroy': True } return value else: so = self.create_folio() folio = self.env['hotel.folio'].search([('reservation_id', '=', self.id)]) for reservation in self: if reservation.other_items_ids: for service_line in reservation.other_items_ids: product_id = self.env['product.product'].search( [('id', '=', service_line.product_id.id)]) if product_id: vals = { 'folio_id': folio.id, 'product_id': product_id.id, 'name': product_id.name, 'product_uom': service_line.product_uom.id, 'product_uom_qty': service_line.product_uom_qty, 'price_unit': service_line.price_unit, } self.env["hotel_service.line"].create(vals) if reservation.food_items_ids: for food_line in reservation.food_items_ids: product_id = self.env['product.product'].search( [('id', '=', food_line.product_id.id)]) if product_id: vals = { 'folio_id': folio.id, 'product_id': product_id.id, 'name': product_id.name, 'product_uom': food_line.product_uom.id, 'product_uom_qty': food_line.product_uom_qty, 'price_unit': food_line.price_unit, } self.env["hotel_food.line"].create(vals) return so class FoodItems(models.Model): _name = "food.items" _description = "Food Items Details" def _amount_line_tax_for_food(self, line): val = 0.0 taxes = line.tax_id.compute_all(line.price_unit * (1 - (line.discount or 0.0) / 100.0), None, line.product_uom_qty) val = taxes['total_included'] - taxes['total_excluded'] return val def _amount_line(self): res = {} cur_obj = self.env['res.currency'] res_user = self.env['res.users'] if self._context is None: self._context = {} for line in self: price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) if line.food_items_id: taxes = line.tax_id.compute_all( price, None, line.product_uom_qty) val = taxes['total_excluded'] cur = line.food_items_id.pricelist_id.currency_id else: taxes = line.tax_id.compute_all( price, None, line.product_uom_qty) val = taxes['total_excluded'] user_id = res_user.browse() cur = user_id.company_id.currency_id # line.update({ # 'price_subtotal': val, # }) line.price_subtotal = val def _amount_line_cost(self): res_user = self.env['res.users'] res = {} if self._context is None: context = {} for line in self: if line.banquet_id: price = line.cost_price_unit taxes = line.pur_tax_ids.compute_all( price, None, line.product_uom_qty) val = taxes['total_excluded'] user_id = res_user.browse(self._uid) cur = user_id.company_id.currency_id # line.update({ # 'cost_price_subtotal': cur.round(val), # }) line.cost_price_subtotal = cur.round(val) return res @api.onchange('product_id') @api.depends('banquet_id.pricelist_id', 'product_uom_qty') def onchange_product_id(self): res = {} # print('context : {}'.format(self.banquet_id)) if self.banquet_id: pricelist = self.banquet_id.pricelist_id.id if not pricelist: raise exceptions.except_orm( 'Warning', 'Price List is not define1.') if self.product_id: record = self.env['product.product'].browse(self.product_id.id) price_unit = self.env['product.pricelist']._price_get( self.product_id, self.product_uom_qty, uom=record.uom_id)[pricelist] if price_unit is False: raise UserError("Could not find a pricelist line matching this product!") res['price_unit'] = price_unit res['price_unit'] = get_price(self, pricelist, record.list_price) res['cost_price_unit'] = get_price( self, pricelist, record.standard_price) res['cost_price_unit'] = record.standard_price res['product_uom'] = record.uom_id.id res['name'] = record.name tax_ids = [] for tax_line in record.taxes_id: tax_ids.append(tax_line.id) res['tax_id'] = [(6, 0, tax_ids)] return {'value': res} def get_subcategory_ids(self, parent_id): all_categ_ids = [] get_ids = [] if parent_id: categ_sub_ids = self.env['product.category'].search( [('parent_id', '=', parent_id)]) if categ_sub_ids: for categ_sub in categ_sub_ids: all_categ_ids.append(categ_sub) get_ids = self.get_subcategory_ids(categ_sub) if get_ids: for get_sub_id in get_ids: all_categ_ids.append(get_sub_id) return all_categ_ids def get_category_id(self): food_categ = [] obj = self.env['product.category'].search([('name', '=', 'Foods')]) categ_ids = self.env['product.category'].search( [('parent_id', '=', obj[0])]) if categ_ids: for categ in categ_ids: food_categ.append(categ) get_categ_ids = self.get_subcategory_ids(categ) if get_categ_ids: for get_categ_id in get_categ_ids: food_categ.append(get_categ_id) food_categ.append(obj[0]) return food_categ food_items_id = fields.Many2one('hotel.reservation') name = fields.Char('Description', required=True, index=True) product_id = fields.Many2one('product.product', 'Product', domain=[( 'sale_ok', '=', True)], change_default=True, help="Will list out all food items that belong to company of selected shop. \n It also shows global product as well.") price_unit = fields.Float( 'Unit Price', required=True, digits='Sale Price', default=0.0) price_subtotal = fields.Float( compute='_amount_line', string='Subtotal', digits='Sale Price') tax_id = fields.Many2many( 'account.tax', 'food_item_tax', 'order_line_id', 'tax_id', 'Taxes') product_uom_qty = fields.Float( 'Quantity (UoM)', digits='Product UoS', default=1) product_uom = fields.Many2one('uom.uom', 'UoM', required=True) discount = fields.Float('Discount (%)', digits=(16, 2), default=0.0) banquet_id = fields.Many2one('banquet.quotation') cost_price_unit = fields.Float('Cost Price', digits='Cost Price') cost_price_subtotal = fields.Float( compute='_amount_line_cost', string='Cost Subtotal', digits='Cost Price') pur_tax_ids = fields.Many2many( 'account.tax', 'pur_tax_tax_line_rel', 'food_id', 'tax_id', 'Purchase Taxes') purches_bol = fields.Boolean('Show Purchase Tax') category_id = fields.Char('Category', default='get_category_id') currency_id = fields.Many2one('res.currency', compute='_compute_currency', string="Currency") @api.depends('banquet_id') def _compute_currency(self): for rec in self: rec.currency_id = rec.banquet_id.pricelist_id.currency_id or rec.banquet_id.company_id.currency_id class OtherItems(models.Model): _name = "other.items" _description = "Other Items Details" def _amount_line(self): res = {} cur_obj = self.env['res.currency'] res_user = self.env['res.users'] if self._context is None: self._context = {} for line in self: price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) if line.other_items_id: taxes = line.tax_id.compute_all( price, None, line.product_uom_qty) val = taxes['total_excluded'] cur = line.other_items_id.pricelist_id.currency_id else: taxes = line.tax_id.compute_all( price, None, line.product_uom_qty) val = taxes['total_excluded'] user_id = res_user.browse() cur = user_id.company_id.currency_id # line.update({ # 'price_subtotal': val, # }) line.price_subtotal = val @api.onchange('product_id') @api.depends('banquet_id.pricelist_id', 'product_uom_qty') def onchange_product_id(self): res = {} if self.banquet_id: pricelist = self.banquet_id.pricelist_id.id if not pricelist: raise UserError('Price List is not define.') if self.product_id: record = self.env['product.product'].browse(self.product_id.id) price_unit = self.env['product.pricelist']._price_get( self.product_id, self.product_uom_qty, uom=record.uom_id)[pricelist] # price_unit = self.env['product.pricelist'].__price_get( # self.product_id.id, self.product_uom_qty, record.uom_id.id)[pricelist] if price_unit is False: raise UserError(_( "Couldn't find a pricelist line matching this product!")) res['price_unit'] = price_unit res['cost_price_unit'] = record.standard_price res['product_uom'] = record.uom_id.id res['name'] = record.name tax_ids = [] for tax_line in record.taxes_id: tax_ids.append(tax_line.id) # res['tax_id'] = [(6, 0, tax_ids)] self.tax_id = [(6, 0, tax_ids)] return {'value': res} def _amount_line_cost(self): res = {} tax_obj = self.env['account.tax'] res_user = self.env['res.users'].search([('id', '=', self._context.get('uid'))]) cur_obj = res_user.company_id.currency_id cur = res_user.company_id.currency_id for line in self: val = 0 if line.banquet_id: price = line.cost_price_unit taxes = line.pur_tax_ids.compute_all( price, None, line.product_uom_qty) val = taxes['total_excluded'] line.update({ 'cost_price_subtotal': cur.round(val) if cur else round(val, 2), }) line.cost_price_subtotal = cur.round(val) if cur else round(val, 2) other_items_id = fields.Many2one('hotel.reservation') name = fields.Char('Description', required=True, index=True) product_id = fields.Many2one('product.product', 'Product', domain=[ ('sale_ok', '=', True), ('isservice', '=', True)], change_default=True) price_unit = fields.Float( 'Unit Price', required=True, digits='Sale Price', default=0.0) price_subtotal = fields.Float( compute='_amount_line', string='Subtotal', digits='Sale Price') tax_id = fields.Many2many( 'account.tax', 'other_service_tax', 'order_line_id', 'tax_id', 'Taxes') product_uom_qty = fields.Float( 'Quantity (UoM)', digits='Product UoS', default=1) product_uom = fields.Many2one('uom.uom', 'UoM', required=True) discount = fields.Float('Discount (%)', digits=(16, 2), default=0.0) banquet_id = fields.Many2one('banquet.quotation') cost_price_unit = fields.Float('Cost Price', digits='Cost Price') cost_price_subtotal = fields.Float( compute='_amount_line_cost', string='Cost Subtotal', digits='Cost Price') pur_tax_ids = fields.Many2many( 'account.tax', 'pur_other_tax_line_rel', 'other_id', 'tax_id', 'Purchase Taxes') purches_bol = fields.Boolean('Show Purchase Tax') currency_id = fields.Many2one('res.currency', compute='_compute_currency', string="Currency") @api.depends('banquet_id') def _compute_currency(self): for rec in self: rec.currency_id = rec.banquet_id.pricelist_id.currency_id or rec.banquet_id.company_id.currency_id class HotelRoom(models.Model): _inherit = "hotel.room" _description = "room Inherit " deposit_bool = fields.Boolean('Is Deposit Applicable', default=True) class BanquetQuotationLeadHistory(models.Model): _name = 'banquet.quotation.lead.history' _description = 'itinerary lead history' ref_id = fields.Many2one('crm.lead', 'History', required=True) name = fields.Char("Banquet Quotation No.", readonly=True) contact_name = fields.Char('Contact Name', readonly=True, ) current_date = fields.Date("Creation Date", required=True, ) update_date = fields.Date("Last Updated Date", required=True, ) state = fields.Selection([ ('draft', 'Draft'), ('confirm', 'Confirm'), ('send_to', 'Send To Customer'), ('approve', 'Approved'), ('refused', 'Refused'), # ('create_tour', 'Create Tour'), ], 'Status', readonly=True)