Compare commits

..

2 Commits
main ... 19.0

Author SHA1 Message Date
f7ffb8b16d initial odoo 19 changes 2025-11-12 16:00:05 +07:00
3328179534 change to odoo 19 2025-11-12 15:59:12 +07:00
27 changed files with 196 additions and 508 deletions

View File

@ -1,78 +1,26 @@
# Purchase Advance Payment
This module allows creating advance payments directly from purchase orders.
When an advance payment is created, a deposit line is automatically added to the PO.
The journal entry uses the expense account from the default advance payment product
and the outstanding payment account from the selected cash/bank journal.
This module allows linking payments to purchase orders as advance payments.
## Features
- Create advance payments directly from Purchase Order form
- Automatic deposit line creation in PO
- Proper accounting entries using:
- Expense account from default advance payment product
- Outstanding payment account from selected journal
- Payment remains in draft state for review before posting
- View all advance payments linked to a PO
- Deposit line automatically updates when payment is posted
## Configuration
1. **Set Default Advance Payment Product**
- Go to **Purchase > Configuration > Settings**
- Scroll to **Advance Payment** section
- Set the **Default Deposit Product** - this product's expense account will be used for advance payment journal entries
2. **Configure Outstanding Payment Accounts** (Choose one option)
**Option A: Journal-Specific** (for multiple banks)
- Go to **Accounting > Configuration > Journals**
- Open each journal > **Outgoing Payments** tab
- Set **Outstanding Payments Account** in payment methods
**Option B: Company Default** (for single bank)
- Go to **Accounting > Configuration > Settings**
- Set **Outstanding Payments Account** in Default Accounts section
Note: Journal-specific accounts take priority over company default.
- Link payments to purchase orders as advance payments
- Automatically subtract advance payments from the total when the PO is fully billed
- Create deposit products on the PO so the final invoice includes the deposit product
- Track advance payments linked to purchase orders
## Usage
### Creating an Advance Payment
1. Create a purchase order
2. Create a payment and link it to the purchase order as an advance payment
3. When the payment is posted, it will automatically be applied as a deposit to the purchase order
4. The deposit will appear as a negative line item on the purchase order
5. When creating the vendor bill, the deposit will be included
1. Open a Purchase Order (must be in confirmed state)
2. Go to **Advance Payments** tab
3. Click **Create Advance Payment** button
4. Fill in the wizard:
- **Journal**: Select cash or bank journal
- **Amount**: Enter advance payment amount
- **Date**: Payment date
- **Memo**: Optional description
5. Click **Confirm**
6. The payment is created in draft state for review
7. A deposit line is automatically added to the PO with negative amount
8. Review the payment and click **Confirm** to post it
## Configuration
### Journal Entry Accounts
When the payment is posted, the journal entry will use:
- **Debit**: Expense account from the default advance payment product
- **Credit**: Outstanding payment account from the selected journal
### Vendor Bill Creation
When creating a vendor bill from the PO:
1. The deposit line will be included in the bill
2. The deposit reduces the total amount payable
3. The advance payment is properly accounted for
## Technical Details
- Module creates a deposit product line in the PO with negative price
- Payment model is extended to handle advance payment accounting
- Journal entries are customized to use correct accounts
- Deposit line updates automatically when payment is posted
No additional configuration is required.
## Known Issues
- None
- None

View File

@ -1,26 +1,20 @@
{
'name': 'Purchase Advance Payment',
'version': '17.0.2.0.0',
'version': '19.0.1.0.0',
'category': 'Purchase',
'summary': 'Create advance payments directly from purchase orders',
'summary': 'Link payments to purchase orders as advance payments',
'description': """
This module allows creating advance payments directly from purchase orders.
When an advance payment is created, a deposit line is automatically added to the PO.
The journal entry uses the expense account from the default advance payment product
and the outstanding payment account from the selected cash/bank journal.
Features:
- Create advance payments from PO form
- Automatic deposit line creation
- Proper accounting with configurable accounts
- Payment remains in draft for review
This module allows linking payments to purchase orders as advance payments.
When a PO is fully billed, the total is subtracted by the advance payment made.
After payment is linked to the PO, a deposit product is created so the final
invoice/vendor bills will include the deposit product.
""",
'author': 'Suherdy Yacob',
'depends': ['purchase', 'account'],
'data': [
'security/ir.model.access.csv',
'data/product_data.xml',
'wizard/create_advance_payment_wizard_views.xml',
'wizard/link_advance_payment_wizard_views.xml',
'views/purchase_advance_payment_views.xml',
'views/purchase_order_views.xml',
'views/res_config_settings_views.xml',
@ -28,4 +22,4 @@
'installable': True,
'auto_install': False,
'license': 'LGPL-3',
}
}

Binary file not shown.

Binary file not shown.

View File

@ -16,75 +16,16 @@ class AccountPayment(models.Model):
help='Identifies if this payment is an advance payment for a purchase order'
)
@api.model_create_multi
def create(self, vals_list):
"""Override create to ensure payment_method_line_id is correctly set for advance payments"""
for vals in vals_list:
# If this is an advance payment and payment_method_line_id is set,
# ensure it matches the journal's payment methods
if vals.get('is_advance_payment') and vals.get('journal_id') and vals.get('payment_method_line_id'):
journal = self.env['account.journal'].browse(vals['journal_id'])
payment_method_line = self.env['account.payment.method.line'].browse(vals['payment_method_line_id'])
# Verify the payment method line belongs to this journal
if payment_method_line not in journal.outbound_payment_method_line_ids:
# If not, find the correct one
correct_method = journal.outbound_payment_method_line_ids.filtered(
lambda l: l.payment_method_id == payment_method_line.payment_method_id
)[:1]
if correct_method:
vals['payment_method_line_id'] = correct_method.id
return super().create(vals_list)
@api.onchange('purchase_order_id')
def _onchange_purchase_order_id(self):
if self.purchase_order_id:
self.amount = self.purchase_order_id.amount_residual
def _prepare_move_line_default_vals(self, write_off_line_vals=None, force_balance=None):
"""Override to use correct accounts for advance payments"""
line_vals_list = super()._prepare_move_line_default_vals(write_off_line_vals=write_off_line_vals, force_balance=force_balance)
if self.is_advance_payment and self.purchase_order_id:
# Get expense account from default deposit product
deposit_product_id = self.env['ir.config_parameter'].sudo().get_param(
'purchase_advance_payment.deposit_product_id')
if deposit_product_id:
product = self.env['product.product'].browse(int(deposit_product_id))
expense_account = product.property_account_expense_id or product.categ_id.property_account_expense_categ_id
if expense_account:
# Get outstanding payment account from journal
# For outbound payments, first check journal-specific account, then company default
outstanding_account = None
# Try to get from journal's outbound payment method
if self.journal_id.outbound_payment_method_line_ids:
outstanding_account = self.journal_id.outbound_payment_method_line_ids[0].payment_account_id
# Fall back to company default if not set on journal
if not outstanding_account:
outstanding_account = self.journal_id.company_id.account_journal_payment_credit_account_id
if outstanding_account:
# Modify the line vals to use correct accounts
for line_vals in line_vals_list:
# The debit line (expense) - partner line
if line_vals.get('debit', 0) > 0 and line_vals.get('partner_id'):
line_vals['account_id'] = expense_account.id
# The credit line (outstanding payment)
elif line_vals.get('credit', 0) > 0:
line_vals['account_id'] = outstanding_account.id
return line_vals_list
def action_post(self):
res = super().action_post()
# When an advance payment is posted, update deposit line in purchase order
# When an advance payment is posted, link it to the purchase order
for payment in self:
if payment.is_advance_payment and payment.purchase_order_id:
# Update the deposit line with the actual posted amount
payment.purchase_order_id._update_deposit_line()
# Apply the deposit to the purchase order
payment.purchase_order_id.action_apply_deposit()
return res

View File

@ -87,57 +87,6 @@ class PurchaseOrder(models.Model):
deposit_lines.unlink()
return res
def _update_deposit_line(self):
"""Update deposit line based on posted advance payments"""
self.ensure_one()
# Calculate total posted advance payments
posted_advance_total = sum(
payment.amount for payment in self.advance_payment_ids.filtered(lambda p: p.state == 'posted')
)
if posted_advance_total <= 0:
# Remove deposit line if no posted payments
deposit_lines = self.order_line.filtered(lambda l: l.is_deposit)
deposit_lines.unlink()
return
# Get or create deposit product
deposit_product_id = self.env['ir.config_parameter'].sudo().get_param(
'purchase_advance_payment.deposit_product_id')
if not deposit_product_id:
raise UserError(
"Please configure a default advance payment product in Purchase settings."
)
deposit_product = self.env['product.product'].browse(int(deposit_product_id))
# Check if deposit line already exists
existing_deposit_line = self.order_line.filtered(lambda l: l.is_deposit)
if existing_deposit_line:
# Update existing deposit line
existing_deposit_line.write({
'product_qty': 1,
'price_unit': -posted_advance_total, # Negative value for deposit
'taxes_id': [(6, 0, [])], # No taxes
})
else:
# Create new deposit line
deposit_vals = {
'order_id': self.id,
'product_id': deposit_product.id,
'name': f'Advance payment for {self.name}',
'product_qty': 1,
'product_uom': deposit_product.uom_id.id,
'price_unit': -posted_advance_total, # Negative value for deposit
'is_deposit': True,
'date_planned': fields.Datetime.now(),
'taxes_id': [(6, 0, [])], # No taxes
}
self.env['purchase.order.line'].create(deposit_vals)
def action_apply_deposit(self):
"""Apply advance payment as deposit line in the purchase order"""
self.ensure_one()

View File

@ -1,2 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_create_advance_payment_wizard,access.create.advance.payment.wizard,model_create_advance_payment_wizard,base.group_user,1,1,1,1
access_link_advance_payment_wizard,access.link.advance.payment.wizard,model_link_advance_payment_wizard,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_create_advance_payment_wizard access_link_advance_payment_wizard access.create.advance.payment.wizard access.link.advance.payment.wizard model_create_advance_payment_wizard model_link_advance_payment_wizard base.group_user 1 1 1 1

View File

@ -15,17 +15,23 @@
required="is_advance_payment"/>
</group>
</xpath>
<!-- Removed Link to PO button as per requirement -->
<xpath expr="//header" position="inside">
<button name="%(purchase_advance_payment.action_link_advance_payment_wizard_payment)d"
string="Link to PO"
type="action"
class="btn-primary"
invisible="state != 'draft' or is_advance_payment"/>
</xpath>
</field>
</record>
<!-- Account Payment Tree View -->
<!-- Account Payment List View -->
<record id="view_account_payment_tree_inherit_advance_payment" model="ir.ui.view">
<field name="name">account.payment.tree.inherit.advance.payment</field>
<field name="model">account.payment</field>
<field name="inherit_id" ref="account.view_account_payment_tree"/>
<field name="arch" type="xml">
<xpath expr="//tree/field[@name='partner_id']" position="after">
<xpath expr="//list/field[@name='partner_id']" position="after">
<field name="purchase_order_id"/>
</xpath>
</field>

View File

@ -16,31 +16,34 @@
<xpath expr="//sheet/notebook" position="inside">
<page string="Advance Payments" name="advance_payments">
<group>
<group>
<field name="advance_payment_total" widget="monetary"/>
<field name="amount_residual" widget="monetary"/>
</group>
<group>
<button name="%(purchase_advance_payment.action_create_advance_payment_wizard)d"
string="Create Advance Payment"
type="action"
<button name="action_apply_deposit"
string="Apply Deposit"
type="object"
class="btn-primary"
context="{'default_purchase_order_id': active_id}"/>
invisible="advance_payment_total &lt;= 0"/>
<button name="%(purchase_advance_payment.action_link_advance_payment_wizard)d"
string="Link Advance Payment"
type="action"
class="btn-secondary"
context="{'default_purchase_order_id': id}"/>
</group>
</group>
<field name="advance_payment_ids" nolabel="1">
<tree create="false" delete="false">
<field name="advance_payment_ids">
<list>
<field name="name"/>
<field name="date"/>
<field name="amount" widget="monetary"/>
<field name="state"/>
<field name="journal_id"/>
</tree>
</list>
</field>
</page>
</xpath>
<xpath expr="//field[@name='order_line']/tree/field[@name='price_unit']" position="after">
<xpath expr="//field[@name='order_line']/list/field[@name='price_unit']" position="after">
<field name="is_deposit" invisible="1"/>
</xpath>

View File

@ -1 +1 @@
from . import create_advance_payment_wizard
from . import link_advance_payment_wizard

View File

@ -1,257 +0,0 @@
from odoo import models, fields, api
from odoo.exceptions import UserError
class CreateAdvancePaymentWizard(models.TransientModel):
_name = 'create.advance.payment.wizard'
_description = 'Create Advance Payment Wizard'
purchase_order_id = fields.Many2one(
'purchase.order',
string='Purchase Order',
required=True,
readonly=True
)
partner_id = fields.Many2one(
'res.partner',
string='Vendor',
related='purchase_order_id.partner_id',
readonly=True
)
journal_id = fields.Many2one(
'account.journal',
string='Journal',
required=True,
domain=[('type', 'in', ['bank', 'cash'])]
)
payment_method_line_id = fields.Many2one(
'account.payment.method.line',
string='Payment Method',
domain="[('id', 'in', available_payment_method_line_ids)]",
help='Manual: Pay by any method outside of Odoo.\n'
'Check: Pay by check and print it from Odoo.\n'
'Batch Deposit: Collect several checks at once.'
)
available_payment_method_line_ids = fields.Many2many(
'account.payment.method.line',
compute='_compute_available_payment_method_line_ids'
)
amount = fields.Monetary(
string='Amount',
required=True,
currency_field='currency_id'
)
currency_id = fields.Many2one(
'res.currency',
string='Currency',
related='purchase_order_id.currency_id',
readonly=True
)
date = fields.Date(
string='Date',
required=True,
default=fields.Date.context_today
)
memo = fields.Char(
string='Memo'
)
expense_account_id = fields.Many2one(
'account.account',
string='Expense Account',
compute='_compute_expense_account',
store=True,
readonly=True
)
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
if self._context.get('default_purchase_order_id'):
po = self.env['purchase.order'].browse(self._context['default_purchase_order_id'])
res['amount'] = po.amount_residual
res['memo'] = f'Advance payment for {po.name}'
return res
@api.depends('journal_id')
def _compute_available_payment_method_line_ids(self):
"""Compute available payment methods based on selected journal"""
for wizard in self:
if wizard.journal_id:
wizard.available_payment_method_line_ids = wizard.journal_id.outbound_payment_method_line_ids
else:
wizard.available_payment_method_line_ids = False
@api.onchange('journal_id')
def _onchange_journal_id(self):
"""Reset payment method when journal changes"""
if self.journal_id:
# Auto-select the first available payment method (usually 'manual')
available_methods = self.journal_id.outbound_payment_method_line_ids
if available_methods:
# Prefer 'manual' payment method
manual_method = available_methods.filtered(
lambda l: l.payment_method_id.code == 'manual'
)[:1]
self.payment_method_line_id = manual_method or available_methods[:1]
else:
self.payment_method_line_id = False
else:
self.payment_method_line_id = False
@api.depends('purchase_order_id')
def _compute_expense_account(self):
"""Get expense account from default advance payment product"""
for wizard in self:
deposit_product_id = self.env['ir.config_parameter'].sudo().get_param(
'purchase_advance_payment.deposit_product_id')
if deposit_product_id:
product = self.env['product.product'].browse(int(deposit_product_id))
# Get expense account from product
account = product.property_account_expense_id or product.categ_id.property_account_expense_categ_id
wizard.expense_account_id = account.id
else:
wizard.expense_account_id = False
def action_create_payment(self):
"""Create advance payment with proper journal entries"""
self.ensure_one()
if self.amount <= 0:
raise UserError("Amount must be greater than zero.")
# Get expense account from default deposit product
if not self.expense_account_id:
raise UserError(
"Please configure a default advance payment product in Purchase settings "
"with a valid expense account."
)
# Get outstanding payment account from journal
# For outbound payments, first check journal-specific account, then company default
outstanding_account = None
# Try to get from journal's outbound payment method
if self.journal_id.outbound_payment_method_line_ids:
outstanding_account = self.journal_id.outbound_payment_method_line_ids[0].payment_account_id
# Fall back to company default if not set on journal
if not outstanding_account:
outstanding_account = self.journal_id.company_id.account_journal_payment_credit_account_id
if not outstanding_account:
raise UserError(
f"Please configure an outstanding payment account for journal '{self.journal_id.name}'.\n"
f"You can set it in:\n"
f"1. Journal level: Accounting > Configuration > Journals > {self.journal_id.name} > "
f"Outgoing Payments tab > Payment Method > Outstanding Payments Account\n"
f"OR\n"
f"2. Company level: Accounting > Configuration > Settings > Default Accounts > "
f"Outstanding Payments Account"
)
# Use the selected payment method line or get the appropriate one
payment_method_line = self.payment_method_line_id
if not payment_method_line:
# Fallback: try to get manual payment method
payment_method_line = self.journal_id.outbound_payment_method_line_ids.filtered(
lambda l: l.payment_method_id.code == 'manual'
)[:1]
if not payment_method_line:
# Fallback to first available outbound payment method
payment_method_line = self.journal_id.outbound_payment_method_line_ids[:1]
if not payment_method_line:
raise UserError(
f"No outbound payment method is configured for journal '{self.journal_id.name}'.\n"
f"Please configure a payment method in: Accounting > Configuration > Journals > "
f"{self.journal_id.name} > Outgoing Payments tab"
)
# Create payment
# CRITICAL: Set payment_type and partner_type FIRST, then journal_id, then payment_method_line_id
# This ensures Odoo's onchange logic correctly filters and sets the payment method
payment_vals = {
'payment_type': 'outbound',
'partner_type': 'supplier',
'partner_id': self.partner_id.id,
'journal_id': self.journal_id.id,
'payment_method_line_id': payment_method_line.id,
'amount': self.amount,
'currency_id': self.currency_id.id,
'date': self.date,
'ref': self.memo or f'Advance payment for {self.purchase_order_id.name}',
'purchase_order_id': self.purchase_order_id.id,
'is_advance_payment': True,
}
payment = self.env['account.payment'].create(payment_vals)
# Force recompute of payment method line to ensure it's correctly set
# This is necessary because Odoo might have changed it during create
if payment.payment_method_line_id != payment_method_line:
payment.write({'payment_method_line_id': payment_method_line.id})
# Create deposit line in purchase order immediately
self._create_deposit_line()
# Return action to open the created payment
return {
'type': 'ir.actions.act_window',
'name': 'Advance Payment',
'res_model': 'account.payment',
'res_id': payment.id,
'view_mode': 'form',
'target': 'current',
}
def _create_deposit_line(self):
"""Create deposit line in purchase order"""
# Get or create deposit product
deposit_product_id = self.env['ir.config_parameter'].sudo().get_param(
'purchase_advance_payment.deposit_product_id')
if not deposit_product_id:
raise UserError(
"Please configure a default advance payment product in Purchase settings."
)
deposit_product = self.env['product.product'].browse(int(deposit_product_id))
# Check if deposit line already exists
existing_deposit_line = self.purchase_order_id.order_line.filtered(lambda l: l.is_deposit)
# Calculate new total advance payment
new_advance_total = self.purchase_order_id.advance_payment_total + self.amount
if existing_deposit_line:
# Update existing deposit line
existing_deposit_line.write({
'product_qty': 1,
'price_unit': -new_advance_total,
'taxes_id': [(6, 0, [])],
})
else:
# Create new deposit line
deposit_vals = {
'order_id': self.purchase_order_id.id,
'product_id': deposit_product.id,
'name': f'Advance payment for {self.purchase_order_id.name}',
'product_qty': 1,
'product_uom': deposit_product.uom_id.id,
'price_unit': -self.amount,
'is_deposit': True,
'date_planned': fields.Datetime.now(),
'taxes_id': [(6, 0, [])],
}
self.env['purchase.order.line'].create(deposit_vals)

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Create Advance Payment Wizard Form View -->
<record id="view_create_advance_payment_wizard_form" model="ir.ui.view">
<field name="name">create.advance.payment.wizard.form</field>
<field name="model">create.advance.payment.wizard</field>
<field name="arch" type="xml">
<form string="Create Advance Payment">
<group>
<group>
<field name="purchase_order_id" readonly="1"/>
<field name="partner_id" readonly="1"/>
<field name="journal_id" required="1"/>
<field name="available_payment_method_line_ids" invisible="1"/>
<field name="payment_method_line_id" required="1"/>
</group>
<group>
<field name="amount" required="1"/>
<field name="currency_id" invisible="1"/>
<field name="date" required="1"/>
<field name="memo"/>
</group>
</group>
<group>
<field name="expense_account_id" readonly="1"/>
</group>
<footer>
<button string="Confirm" name="action_create_payment" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<!-- Create Advance Payment Wizard Action -->
<record id="action_create_advance_payment_wizard" model="ir.actions.act_window">
<field name="name">Create Advance Payment</field>
<field name="res_model">create.advance.payment.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,107 @@
from odoo import models, fields, api
from odoo.exceptions import UserError
class LinkAdvancePaymentWizard(models.TransientModel):
_name = 'link.advance.payment.wizard'
_description = 'Link Advance Payment Wizard'
purchase_order_id = fields.Many2one(
'purchase.order',
string='Purchase Order'
)
payment_id = fields.Many2one(
'account.payment',
string='Payment',
domain=[('state', '=', 'draft')]
)
amount = fields.Monetary(
string='Amount'
)
currency_id = fields.Many2one(
'res.currency',
string='Currency'
)
@api.model
def default_get(self, fields):
res = super().default_get(fields)
# Handle context from purchase order
if self.env.context.get('active_model') == 'purchase.order' and self.env.context.get('active_id'):
po = self.env['purchase.order'].browse(self.env.context['active_id'])
res['purchase_order_id'] = po.id
res['currency_id'] = po.currency_id.id
if 'amount' in fields:
res['amount'] = po.amount_residual
# Handle context from purchase order when called from the button (using default_purchase_order_id)
elif self.env.context.get('default_purchase_order_id'):
po = self.env['purchase.order'].browse(self.env.context['default_purchase_order_id'])
res['purchase_order_id'] = po.id
res['currency_id'] = po.currency_id.id
if 'amount' in fields and 'amount' not in res:
res['amount'] = po.amount_residual
# Handle context from payment
elif self.env.context.get('active_model') == 'account.payment' and self.env.context.get('active_id'):
payment = self.env['account.payment'].browse(self.env.context['active_id'])
res['payment_id'] = payment.id
res['currency_id'] = payment.currency_id.id
if 'amount' in fields:
res['amount'] = payment.amount
return res
@api.onchange('payment_id')
def _onchange_payment_id(self):
if self.payment_id:
self.currency_id = self.payment_id.currency_id.id
self.amount = self.payment_id.amount
# Filter purchase orders by partner when payment is selected
if self.payment_id.partner_id:
purchase_orders = self.env['purchase.order'].search([
('partner_id', '=', self.payment_id.partner_id.id),
('state', 'in', ['purchase', 'done'])
])
return {'domain': {'purchase_order_id': [('id', 'in', purchase_orders.ids)]}}
return {'domain': {'purchase_order_id': []}}
@api.onchange('purchase_order_id')
def _onchange_purchase_order_id(self):
if self.purchase_order_id:
self.currency_id = self.purchase_order_id.currency_id.id
self.amount = self.purchase_order_id.amount_residual
# Filter payments by partner when purchase order is selected
if self.purchase_order_id.partner_id:
payments = self.env['account.payment'].search([
('partner_id', '=', self.purchase_order_id.partner_id.id),
('state', '=', 'draft'),
('payment_type', '=', 'outbound')
])
return {'domain': {'payment_id': [('id', 'in', payments.ids)]}}
return {'domain': {'payment_id': []}}
def action_link_payment(self):
self.ensure_one()
if self.amount <= 0:
raise UserError("Amount must be greater than zero.")
# Check if we have both payment and purchase order
if not self.payment_id:
raise UserError("Payment must be specified.")
if not self.purchase_order_id:
raise UserError("Purchase order must be specified.")
# Link the payment to the purchase order
self.payment_id.write({
'purchase_order_id': self.purchase_order_id.id,
'is_advance_payment': True,
'amount': self.amount
})
return {
'type': 'ir.actions.act_window_close'
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Link Advance Payment Wizard Form View -->
<record id="view_link_advance_payment_wizard_form" model="ir.ui.view">
<field name="name">link.advance.payment.wizard.form</field>
<field name="model">link.advance.payment.wizard</field>
<field name="arch" type="xml">
<form string="Link Advance Payment">
<group>
<field name="purchase_order_id"/>
<field name="payment_id" domain="[('state', '=', 'draft'), ('payment_type', '=', 'outbound')]"/>
<field name="amount"/>
<field name="currency_id" invisible="1"/>
</group>
<footer>
<button string="Link Payment" name="action_link_payment" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<!-- Link Advance Payment Wizard Action -->
<record id="action_link_advance_payment_wizard" model="ir.actions.act_window">
<field name="name">Link Advance Payment</field>
<field name="res_model">link.advance.payment.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<!-- Link Advance Payment Wizard Action from Payment -->
<record id="action_link_advance_payment_wizard_payment" model="ir.actions.act_window">
<field name="name">Link to Purchase Order</field>
<field name="res_model">link.advance.payment.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="context">{'active_model': 'account.payment', 'active_id': active_id}</field>
</record>
</data>
</odoo>