mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[WIP] workflow invoices
This commit is contained in:
@@ -257,10 +257,32 @@ class HotelFolio(models.Model):
|
||||
for record in self:
|
||||
record.rooms_char = ', '.join(record.mapped('room_lines.room_id.name'))
|
||||
|
||||
# @api.depends('order_line.price_total', 'payment_ids', 'return_ids')
|
||||
@api.depends('amount_total', 'payment_ids', 'return_ids')
|
||||
@api.multi
|
||||
def compute_amount(self):
|
||||
_logger.info('compute_amount')
|
||||
acc_pay_obj = self.env['account.payment']
|
||||
for record in self:
|
||||
if record.reservation_type in ('staff', 'out'):
|
||||
vals = {
|
||||
'pending_amount': 0,
|
||||
'invoices_paid': 0,
|
||||
'refund_amount': 0,
|
||||
}
|
||||
record.update(vals)
|
||||
else:
|
||||
total_inv_refund = 0
|
||||
payments = acc_pay_obj.search([
|
||||
('folio_id', '=', record.id)
|
||||
])
|
||||
total_paid = sum(pay.amount for pay in payments)
|
||||
return_lines = self.env['payment.return.line'].search([('move_line_ids','in',payments.mapped('move_line_ids.id')),('return_id.state','=', 'done')])
|
||||
total_inv_refund = sum(pay_return.amount for pay_return in return_lines)
|
||||
vals = {
|
||||
'pending_amount': record.amount_total - total_paid + total_inv_refund,
|
||||
'invoices_paid': total_paid,
|
||||
'refund_amount': total_inv_refund,
|
||||
}
|
||||
record.update(vals)
|
||||
|
||||
@api.multi
|
||||
def action_pay(self):
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# Copyright 2017-2018 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
import time
|
||||
from datetime import timedelta
|
||||
from lxml import etree
|
||||
@@ -14,6 +13,7 @@ from odoo.tools import (
|
||||
DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.addons import decimal_precision as dp
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -168,6 +168,7 @@ class HotelReservation(models.Model):
|
||||
track_visibility='onchange')
|
||||
reservation_type = fields.Selection(related='folio_id.reservation_type',
|
||||
default=lambda *a: 'normal')
|
||||
invoice_count = fields.Integer(related='folio_id.invoice_count')
|
||||
board_service_room_id = fields.Many2one('hotel.board.service.room.type',
|
||||
string='Board Service')
|
||||
cancelled_reason = fields.Selection([
|
||||
@@ -333,11 +334,13 @@ class HotelReservation(models.Model):
|
||||
board_services = []
|
||||
board = self.env['hotel.board.service.room.type'].browse(vals['board_service_room_id'])
|
||||
for line in board.board_service_line_ids:
|
||||
board_services.append((0, False, {
|
||||
res = {
|
||||
'product_id': line.product_id.id,
|
||||
'is_board_service': True,
|
||||
'folio_id': vals.get('folio_id'),
|
||||
}))
|
||||
}
|
||||
res.update(self.env['hotel.service']._prepare_add_missing_fields(res))
|
||||
board_services.append((0, False, res))
|
||||
vals.update({'service_ids': board_services})
|
||||
if self.compute_price_out_vals(vals):
|
||||
days_diff = (
|
||||
@@ -382,18 +385,15 @@ class HotelReservation(models.Model):
|
||||
board_services = []
|
||||
board = self.env['hotel.board.service.room.type'].browse(vals['board_service_room_id'])
|
||||
for line in board.board_service_line_ids:
|
||||
board_services.append((0, False, {
|
||||
res = {
|
||||
'product_id': line.product_id.id,
|
||||
'is_board_service': True,
|
||||
'folio_id': record.folio_id.id or vals.get('folio_id')
|
||||
}))
|
||||
'folio_id': vals.get('folio_id'),
|
||||
}
|
||||
res.update(self.env['hotel.service']._prepare_add_missing_fields(res))
|
||||
board_services.append((0, False, vals))
|
||||
# NEED REVIEW: Why I need add manually the old IDs if board service is (0,0,(-)) ¿?¿?¿
|
||||
record.update({'service_ids': [(6, 0, record.service_ids.ids)] + board_services})
|
||||
update_services = record.service_ids.filtered(
|
||||
lambda r: r.is_board_service == True
|
||||
)
|
||||
for service in update_services:
|
||||
service.onchange_product_calc_qty()
|
||||
if record.compute_price_out_vals(vals):
|
||||
record.update(record.prepare_reservation_lines(
|
||||
checkin,
|
||||
@@ -457,7 +457,7 @@ class HotelReservation(models.Model):
|
||||
line = self.new(values)
|
||||
if any(f not in values for f in onchange_fields):
|
||||
line.onchange_room_id()
|
||||
line.onchange_compute_reservation_description()
|
||||
line.onchange_room_type_id()
|
||||
line.onchange_board_service()
|
||||
if 'pricelist_id' not in values:
|
||||
line.onchange_partner_id()
|
||||
@@ -625,7 +625,10 @@ class HotelReservation(models.Model):
|
||||
update_old_prices=False))
|
||||
|
||||
@api.onchange('checkin', 'checkout', 'room_type_id')
|
||||
def onchange_compute_reservation_description(self):
|
||||
def onchange_room_type_id(self):
|
||||
"""
|
||||
When change de room_type_id, we calc the line description and tax_ids
|
||||
"""
|
||||
if self.room_type_id and self.checkin and self.checkout:
|
||||
checkin_dt = fields.Date.from_string(self.checkin)
|
||||
checkout_dt = fields.Date.from_string(self.checkout)
|
||||
@@ -633,6 +636,7 @@ class HotelReservation(models.Model):
|
||||
checkout_str = checkout_dt.strftime('%d/%m/%Y')
|
||||
self.name = self.room_type_id.name + ': ' + checkin_str + ' - '\
|
||||
+ checkout_str
|
||||
self._compute_tax_ids()
|
||||
|
||||
@api.onchange('checkin', 'checkout')
|
||||
def onchange_update_service_per_day(self):
|
||||
@@ -670,18 +674,20 @@ class HotelReservation(models.Model):
|
||||
for line in self.board_service_room_id.board_service_line_ids:
|
||||
product = line.product_id
|
||||
if product.per_day:
|
||||
vals = {
|
||||
res = {
|
||||
'product_id': product.id,
|
||||
'is_board_service': True,
|
||||
'folio_id': self.folio_id.id,
|
||||
}
|
||||
vals.update(self.env['hotel.service'].prepare_service_lines(
|
||||
line = self.env['hotel.service'].new(res)
|
||||
res.update(self.env['hotel.service']._prepare_add_missing_fields(res))
|
||||
res.update(self.env['hotel.service'].prepare_service_lines(
|
||||
dfrom=self.checkin,
|
||||
days=self.nights,
|
||||
per_person=product.per_person,
|
||||
persons=self.adults,
|
||||
old_line_days=False))
|
||||
board_services.append((0, False, vals))
|
||||
board_services.append((0, False, res))
|
||||
other_services = self.service_ids.filtered(lambda r: r.is_board_service == False)
|
||||
self.update({'service_ids': [(6, 0, other_services.ids)] + board_services})
|
||||
for service in self.service_ids.filtered(lambda r: r.is_board_service == True):
|
||||
@@ -1162,6 +1168,29 @@ class HotelReservation(models.Model):
|
||||
INVOICING PROCESS
|
||||
"""
|
||||
|
||||
@api.multi
|
||||
def open_invoices_reservation(self):
|
||||
invoices = self.folio_id.mapped('invoice_ids')
|
||||
action = self.env.ref('account.action_invoice_tree1').read()[0]
|
||||
if len(invoices) > 1:
|
||||
action['domain'] = [('id', 'in', invoices.ids)]
|
||||
elif len(invoices) == 1:
|
||||
action['views'] = [(self.env.ref('account.invoice_form').id, 'form')]
|
||||
action['res_id'] = invoices.ids[0]
|
||||
else:
|
||||
action = self.env.ref('hotel.action_view_folio_advance_payment_inv').read()[0]
|
||||
action['context'] = {'default_reservation_id': self.id,
|
||||
'default_folio_id': self.folio_id.id}
|
||||
return action
|
||||
|
||||
@api.multi
|
||||
def _compute_tax_ids(self):
|
||||
for record in self:
|
||||
# If company_id is set, always filter taxes by the company
|
||||
folio = record.folio_id or self.env.context.get('default_folio_id')
|
||||
product = self.env['product.product'].browse(record.room_type_id.product_id.id)
|
||||
record.tax_ids = product.taxes_id.filtered(lambda r: not record.company_id or r.company_id == folio.company_id)
|
||||
|
||||
@api.depends('qty_invoiced', 'nights', 'folio_id.state')
|
||||
def _get_to_invoice_qty(self):
|
||||
"""
|
||||
|
||||
@@ -206,7 +206,7 @@ class HotelService(models.Model):
|
||||
def _prepare_add_missing_fields(self, values):
|
||||
""" Deduce missing required fields from the onchange """
|
||||
res = {}
|
||||
onchange_fields = ['price_unit','tax_ids']
|
||||
onchange_fields = ['price_unit','tax_ids','name']
|
||||
if values.get('product_id'):
|
||||
line = self.new(values)
|
||||
if any(f not in values for f in onchange_fields):
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
</button>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
|
||||
<!-- <button type="object" class="oe_stat_button"
|
||||
<button type="object" class="oe_stat_button"
|
||||
id="invoices_smart_button"
|
||||
icon="fa-thumbs-up"
|
||||
name="action_payments"
|
||||
@@ -78,9 +78,9 @@
|
||||
</span>
|
||||
<span class="o_stat_text">Paid out</span>
|
||||
</div>
|
||||
</button> -->
|
||||
</button>
|
||||
|
||||
<!-- <button type="object" class="oe_stat_button"
|
||||
<button type="object" class="oe_stat_button"
|
||||
id="payment_smart_button"
|
||||
icon="fa-money"
|
||||
name="action_pay"
|
||||
@@ -92,9 +92,9 @@
|
||||
</span>
|
||||
<span class="o_stat_text">Pending Payment</span>
|
||||
</div>
|
||||
</button> -->
|
||||
</button>
|
||||
|
||||
<!-- <button type="object" class="oe_stat_button"
|
||||
<button type="object" class="oe_stat_button"
|
||||
id="refunds_smart_button"
|
||||
icon="fa-undo"
|
||||
name="action_return_payments"
|
||||
@@ -106,7 +106,7 @@
|
||||
</span>
|
||||
<span class="o_stat_text">Refunds</span>
|
||||
</div>
|
||||
</button> -->
|
||||
</button>
|
||||
|
||||
<button type="object" class="oe_stat_button" id="invoice_button"
|
||||
icon="fa-pencil-square-o" name="open_invoices_folio"
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
<form string="Reservation" >
|
||||
<header>
|
||||
<field name="splitted" invisible="True" />
|
||||
<field name="tax_ids" invisible="1"/>
|
||||
<field name="parent_reservation" invisible="True" />
|
||||
<field name="has_confirmed_reservations_to_send" invisible="1" />
|
||||
<field name="has_cancelled_reservations_to_send" invisible="1" />
|
||||
<field name="tax_ids" invisible="1"/>
|
||||
<field name="has_checkout_to_send" invisible="1" />
|
||||
<button name="send_reservation_mail" type="object" string="Send Confirmation Email"
|
||||
attrs="{'invisible': [('has_confirmed_reservations_to_send', '=', False)]}" class="oe_highlight"/>
|
||||
@@ -99,6 +99,15 @@
|
||||
<span class="o_stat_text">Books</span>
|
||||
</div>
|
||||
</button>
|
||||
<button type="object" class="oe_stat_button" id="invoice_button"
|
||||
icon="fa-pencil-square-o" name="open_invoices_reservation">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_value">
|
||||
<field name="invoice_count"/>
|
||||
</span>
|
||||
<span class="o_stat_text">Invoices</span>
|
||||
</div>
|
||||
</button>
|
||||
<button type="object" class="oe_stat_button"
|
||||
id="open_master"
|
||||
icon="fa-chain-broken"
|
||||
|
||||
@@ -16,42 +16,52 @@
|
||||
<field name="model">account.payment</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Register Payment" version="7">
|
||||
<header>
|
||||
<button name="post" class="oe_highlight" states="draft" string="Confirm" type="object"/>
|
||||
<button name="action_draft" class="oe_highlight" states="cancelled" string="Set To Draft" type="object"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,posted,reconciled,cancelled"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" name="button_journal_entries" string="Journal Items" type="object" groups="account.group_account_manager" attrs="{'invisible':[('move_line_ids','=',[])]}" icon="fa-bars"/>
|
||||
<button class="oe_stat_button" name="button_journal_entries"
|
||||
string="Journal Items" type="object"
|
||||
groups="account.group_account_user"
|
||||
attrs="{'invisible':[('move_line_ids','=',[])]}" icon="fa-bars"/>
|
||||
<field name="move_line_ids" invisible="1"/>
|
||||
<button class="oe_stat_button" name="button_invoices" string="Invoices" type="object" attrs="{'invisible':[('has_invoices','=',False)]}" icon="fa-bars"/>
|
||||
<button class="oe_stat_button" name="button_invoices"
|
||||
string="Invoices" type="object"
|
||||
attrs="{'invisible':[('has_invoices','=',False)]}" icon="fa-bars"/>
|
||||
<button class="oe_stat_button" name="open_payment_matching_screen"
|
||||
string="Payment Matching" type="object"
|
||||
attrs="{'invisible':[('move_reconciled','=',True)]}" icon="fa-university"/>
|
||||
<field name="has_invoices" invisible="1"/>
|
||||
<field name="move_reconciled" invisible="1"/>
|
||||
</div>
|
||||
<field name="id" invisible="1"/>
|
||||
<div class="oe_title" attrs="{'invisible': [('state', '=', 'draft')]}">
|
||||
<h1><field name="name"/></h1>
|
||||
</div>
|
||||
<group>
|
||||
<field name="payment_type" invisible="1"/>
|
||||
<field name="partner_type" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<group>
|
||||
<field name="journal_id" widget="selection"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="hide_payment_method" invisible="1"/>
|
||||
<field name="payment_method_id" widget="radio" attrs="{'invisible': [('hide_payment_method', '=', True)]}"/>
|
||||
<field name="payment_method_code" invisible="1"/>
|
||||
<field name="payment_type" widget="radio" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="partner_type" widget="selection" attrs="{'required': [('state', '=', 'draft'), ('payment_type', 'in', ('inbound', 'outbound'))], 'invisible': [('payment_type', 'not in', ('inbound', 'outbound'))], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="partner_id" attrs="{'required': [('state', '=', 'draft'), ('payment_type', 'in', ('inbound', 'outbound'))], 'invisible': [('payment_type', 'not in', ('inbound', 'outbound'))], 'readonly': [('state', '!=', 'draft')]}" context="{'default_is_company': True, 'default_supplier': payment_type == 'outbound', 'default_customer': payment_type == 'inbound'}"/>
|
||||
<label for="amount"/>
|
||||
<div name="amount_div" class="o_row">
|
||||
<field name="amount"/>
|
||||
<field name="amount" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="currency_id" options="{'no_create': True, 'no_open': True}" groups="base.group_multi_currency" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
</div>
|
||||
<field name="journal_id" widget="selection" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="destination_journal_id" widget="selection" attrs="{'required': [('payment_type', '=', 'transfer')], 'invisible': [('payment_type', '!=', 'transfer')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="hide_payment_method" invisible="1"/>
|
||||
<field name="payment_method_id" string=" " widget="radio" attrs="{'invisible': [('hide_payment_method', '=', True)], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="payment_method_code" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="payment_date"/>
|
||||
<field name="communication"/>
|
||||
<field name="payment_date" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="communication" attrs="{'invisible': [('state', '!=', 'draft'), ('communication', '=', False)], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="folio_id"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('payment_difference', '=', 0.0)]}">
|
||||
<label for="payment_difference"/>
|
||||
<div>
|
||||
<field name="payment_difference"/>
|
||||
<field name="payment_difference_handling" widget="radio" nolabel="1"/>
|
||||
</div>
|
||||
<field name="writeoff_account_id" string="Post Difference In"
|
||||
attrs="{'invisible': [('payment_difference_handling','=','open')], 'required': [('payment_difference_handling', '=', 'reconcile')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<footer>
|
||||
@@ -65,6 +75,10 @@
|
||||
attrs="{'invisible': [('state','=','draft')]}"/>
|
||||
<button string="Cancel" class="btn-default" special="cancel"/>
|
||||
</footer>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -27,20 +27,29 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
|
||||
@api.model
|
||||
def _get_default_folio(self):
|
||||
folios = self.env['hotel.folio'].browse(self._context.get('active_ids', []))
|
||||
if self._context.get('default_reservation_id'):
|
||||
folio_ids = self._context.get('default_folio_id', [])
|
||||
else:
|
||||
folio_ids = self._context.get('active_ids', [])
|
||||
|
||||
folios = self.env['hotel.folio'].browse(folio_ids)
|
||||
return folios
|
||||
|
||||
@api.model
|
||||
def _get_default_reservation(self):
|
||||
folios = self._get_default_folio()
|
||||
reservations = self.env['hotel.reservation']
|
||||
for folio in folios:
|
||||
reservations |= folio.room_lines
|
||||
if self._context.get('default_reservation_id'):
|
||||
reservations = self.env['hotel.reservation'].browse(self._context.get('active_ids', []))
|
||||
else:
|
||||
folios = self._get_default_folio()
|
||||
reservations = self.env['hotel.reservation']
|
||||
for folio in folios:
|
||||
reservations |= folio.room_lines
|
||||
return reservations
|
||||
|
||||
@api.model
|
||||
def _get_default_partner_invoice(self):
|
||||
return self.env['hotel.folio'].browse(self._context.get('active_id', [])).partner_invoice_id
|
||||
folios = self._get_default_folio()
|
||||
return folios[0].partner_invoice_id
|
||||
|
||||
@api.model
|
||||
def _default_deposit_account_id(self):
|
||||
@@ -72,9 +81,6 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
'advance_inv_id',
|
||||
string="Invoice Lines")
|
||||
view_detail = fields.Boolean('View Detail')
|
||||
line_ids = fields.One2many('line.advance.inv',
|
||||
'advance_inv_id',
|
||||
string="Lines")
|
||||
#Advance Payment
|
||||
product_id = fields.Many2one('product.product', string="Product",
|
||||
domain=[('type', '=', 'service')], default=_default_product_id)
|
||||
@@ -215,7 +221,24 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
'tax_id': [(6, 0, tax_ids)],
|
||||
})
|
||||
del context
|
||||
self._create_invoice(folio, service_line, amount)
|
||||
invoice = self._create_invoice(folio, service_line, amount)
|
||||
invoice.compute_taxes()
|
||||
if not invoice.invoice_line_ids:
|
||||
raise UserError(_('There is no invoiceable line.'))
|
||||
# If invoice is negative, do a refund invoice instead
|
||||
if invoice.amount_total < 0:
|
||||
invoice.type = 'out_refund'
|
||||
for line in invoice.invoice_line_ids:
|
||||
line.quantity = -line.quantity
|
||||
# Use additional field helper function (for account extensions)
|
||||
for line in invoice.invoice_line_ids:
|
||||
line._set_additional_fields(invoice)
|
||||
# Necessary to force computation of taxes. In account_invoice, they are triggered
|
||||
# by onchanges, which are not triggered when doing a create.
|
||||
invoice.compute_taxes()
|
||||
invoice.message_post_with_view('mail.message_origin_link',
|
||||
values={'self': invoice, 'origin': folios},
|
||||
subtype_id=self.env.ref('mail.mt_note').id)
|
||||
if self._context.get('open_invoices', False):
|
||||
return folios.open_invoices_folio()
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
@@ -307,11 +330,12 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
invoice_lines = {}
|
||||
reservations = self.env['hotel.reservation']
|
||||
services = self.env['hotel.service']
|
||||
for folio in folios:
|
||||
old_folio_ids = self.reservation_ids.mapped('folio_id.id')
|
||||
for folio in folios.filtered(lambda r: r.id not in old_folio_ids):
|
||||
folio_reservations = folio.room_lines
|
||||
if folio_reservations:
|
||||
reservations |= folio_reservations
|
||||
self.reservation_ids = reservations
|
||||
self.reservation_ids |= reservations
|
||||
self.prepare_invoice_lines()
|
||||
|
||||
@api.model
|
||||
@@ -369,6 +393,12 @@ class LineAdvancePaymentInv(models.TransientModel):
|
||||
description = fields.Text('Description')
|
||||
reservation_id = fields.Many2one('hotel.reservation')
|
||||
service_id = fields.Many2one('hotel.service')
|
||||
folio_id = fields.Many2one('hotel.folio', compute='_compute_folio_id')
|
||||
|
||||
def _compute_folio_id(self):
|
||||
for record in self:
|
||||
origin = record.reservation_id if record.reservation_id.id else record.service_id
|
||||
record.folio_id = origin.folio_id
|
||||
|
||||
@api.multi
|
||||
def invoice_line_create(self, invoice_id, qty):
|
||||
@@ -380,7 +410,7 @@ class LineAdvancePaymentInv(models.TransientModel):
|
||||
invoice_lines = self.env['account.invoice.line']
|
||||
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
|
||||
for line in self:
|
||||
origin = self.reservation_id if self.reservation_id.id else self.service_id
|
||||
origin = line.reservation_id if line.reservation_id.id else line.service_id
|
||||
res = {}
|
||||
product = line.product_id
|
||||
account = product.property_account_income_id or product.categ_id.property_account_income_categ_id
|
||||
@@ -388,7 +418,7 @@ class LineAdvancePaymentInv(models.TransientModel):
|
||||
raise UserError(_('Please define income account for this product: "%s" (id:%d) - or for its category: "%s".') %
|
||||
(product.name, product.id, product.categ_id.name))
|
||||
|
||||
fpos = origin.folio_id.fiscal_position_id or origin.folio_id.partner_id.property_account_position_id
|
||||
fpos = line.folio_id.fiscal_position_id or line.folio_id.partner_id.property_account_position_id
|
||||
if fpos:
|
||||
account = fpos.map_account(account)
|
||||
|
||||
@@ -403,10 +433,13 @@ class LineAdvancePaymentInv(models.TransientModel):
|
||||
'uom_id': product.uom_id.id,
|
||||
'product_id': product.id or False,
|
||||
'invoice_line_tax_ids': [(6, 0, origin.tax_ids.ids)],
|
||||
'account_analytic_id': origin.folio_id.analytic_account_id.id,
|
||||
'account_analytic_id': line.folio_id.analytic_account_id.id,
|
||||
'analytic_tag_ids': [(6, 0, origin.analytic_tag_ids.ids)],
|
||||
}
|
||||
vals.update({'invoice_id': invoice_id, 'reservation_ids': [(6, 0, [origin.id])]})
|
||||
if line.reservation_id:
|
||||
vals.update({'invoice_id': invoice_id, 'reservation_ids': [(6, 0, [origin.id])]})
|
||||
elif line.service_id:
|
||||
vals.update({'invoice_id': invoice_id, 'service_ids': [(6, 0, [origin.id])]})
|
||||
invoice_lines |= self.env['account.invoice.line'].create(vals)
|
||||
|
||||
return invoice_lines
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
<tree string="Lines" editable="bottom">
|
||||
<field name="product_id" invisible="1"/>
|
||||
<field name="reservation_id" />
|
||||
<field name="service_id" />
|
||||
<field name="description" />
|
||||
<field name="qty" />
|
||||
<field name="discount" />
|
||||
|
||||
Reference in New Issue
Block a user