From c3d84d61e8104741b657204a5e79fe0aedebfbc5 Mon Sep 17 00:00:00 2001
From: kongrattapong
Date: Mon, 19 Aug 2019 13:41:42 +0700
Subject: [PATCH 01/49] [12.0][ADD] Purchase Invoice Plan
---
purchase_invoice_plan/__init__.py | 5 +
purchase_invoice_plan/__manifest__.py | 23 +
purchase_invoice_plan/models/__init__.py | 4 +
purchase_invoice_plan/models/purchase.py | 243 ++++++++++
purchase_invoice_plan/readme/CONTRIBUTORS.rst | 2 +
purchase_invoice_plan/readme/DESCRIPTION.rst | 4 +
purchase_invoice_plan/readme/USAGE.rst | 7 +
.../security/ir.model.access.csv | 2 +
.../static/description/index.html | 435 ++++++++++++++++++
purchase_invoice_plan/tests/__init__.py | 4 +
.../tests/test_purchase_invoice_plan.py | 102 ++++
purchase_invoice_plan/views/purchase_view.xml | 149 ++++++
purchase_invoice_plan/wizard/__init__.py | 4 +
.../wizard/purchase_create_invoice_plan.py | 53 +++
.../purchase_create_invoice_plan_view.xml | 48 ++
.../wizard/purchase_make_planned_invoice.py | 22 +
.../purchase_make_planned_invoice_view.xml | 41 ++
17 files changed, 1148 insertions(+)
create mode 100644 purchase_invoice_plan/__init__.py
create mode 100644 purchase_invoice_plan/__manifest__.py
create mode 100644 purchase_invoice_plan/models/__init__.py
create mode 100644 purchase_invoice_plan/models/purchase.py
create mode 100644 purchase_invoice_plan/readme/CONTRIBUTORS.rst
create mode 100644 purchase_invoice_plan/readme/DESCRIPTION.rst
create mode 100644 purchase_invoice_plan/readme/USAGE.rst
create mode 100644 purchase_invoice_plan/security/ir.model.access.csv
create mode 100644 purchase_invoice_plan/static/description/index.html
create mode 100644 purchase_invoice_plan/tests/__init__.py
create mode 100644 purchase_invoice_plan/tests/test_purchase_invoice_plan.py
create mode 100644 purchase_invoice_plan/views/purchase_view.xml
create mode 100644 purchase_invoice_plan/wizard/__init__.py
create mode 100644 purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
create mode 100644 purchase_invoice_plan/wizard/purchase_create_invoice_plan_view.xml
create mode 100644 purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
create mode 100644 purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
diff --git a/purchase_invoice_plan/__init__.py b/purchase_invoice_plan/__init__.py
new file mode 100644
index 00000000000..d5a964721a2
--- /dev/null
+++ b/purchase_invoice_plan/__init__.py
@@ -0,0 +1,5 @@
+# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
+
+from . import models
+from . import wizard
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
new file mode 100644
index 00000000000..73faaa341df
--- /dev/null
+++ b/purchase_invoice_plan/__manifest__.py
@@ -0,0 +1,23 @@
+# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
+
+{
+ 'name': 'Purchase Invoice Plan',
+ 'summary': 'Add to purchases order, ability to manage future invoice plan',
+ 'version': '12.0.1.0.0',
+ 'author': 'Ecosoft,Odoo Community Association (OCA)',
+ 'license': 'AGPL-3',
+ 'website': 'https://github.com/OCA/purchase-workflow/',
+ 'category': 'Purchase',
+ 'depends': ['account',
+ 'purchase_open_qty',
+ 'purchase_stock',
+ ],
+ 'data': ['security/ir.model.access.csv',
+ 'wizard/purchase_create_invoice_plan_view.xml',
+ 'wizard/purchase_make_planned_invoice_view.xml',
+ 'views/purchase_view.xml',
+ ],
+ 'installable': True,
+ 'development_status': 'alpha',
+}
diff --git a/purchase_invoice_plan/models/__init__.py b/purchase_invoice_plan/models/__init__.py
new file mode 100644
index 00000000000..8f3730cc9fe
--- /dev/null
+++ b/purchase_invoice_plan/models/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
+
+from . import purchase
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
new file mode 100644
index 00000000000..1862206c33c
--- /dev/null
+++ b/purchase_invoice_plan/models/purchase.py
@@ -0,0 +1,243 @@
+# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
+
+from dateutil.relativedelta import relativedelta
+from odoo import models, fields, api, _
+from odoo.exceptions import UserError, ValidationError
+from odoo.addons import decimal_precision as dp
+from odoo.tools.float_utils import float_compare, float_round
+
+
+class PurchaseOrder(models.Model):
+ _inherit = 'purchase.order'
+
+ invoice_plan_ids = fields.One2many(
+ comodel_name='purchase.invoice.plan',
+ inverse_name='purchase_id',
+ string='Inovice Plan',
+ copy=False,
+ readonly=True,
+ states={'draft': [('readonly', False)]},
+ )
+ use_invoice_plan = fields.Boolean(
+ string='Use Invoice Plan',
+ default=False,
+ copy=False,
+ )
+ ip_invoice_plan = fields.Boolean(
+ string='Invoice Plan In Process',
+ compute='_compute_ip_invoice_plan',
+ help="At least one invoice plan line pending to create invoice",
+ )
+
+ @api.multi
+ def _compute_ip_invoice_plan(self):
+ for rec in self:
+ rec.ip_invoice_plan = rec.use_invoice_plan and \
+ rec.invoice_plan_ids and \
+ len(rec.invoice_plan_ids.filtered(lambda l: not l.invoiced))
+
+ @api.constrains('state')
+ def _check_invoice_plan(self):
+ for rec in self:
+ if rec.state != 'draft':
+ if rec.invoice_plan_ids.filtered(lambda l: not l.percent):
+ raise ValidationError(
+ _('Please fill percentage for all invoice plan lines'))
+
+ @api.multi
+ def action_confirm(self):
+ if self.filtered(lambda r: r.use_invoice_plan
+ and not r.invoice_plan_ids):
+ raise UserError(
+ _('Use Invoice Plan selected, but no plan created'))
+ return super().action_confirm()
+
+ @api.multi
+ def create_invoice_plan(self, num_installment, installment_date,
+ interval, interval_type):
+ self.ensure_one()
+ self.invoice_plan_ids.unlink()
+ invoice_plans = []
+ Decimal = self.env['decimal.precision']
+ prec = Decimal.precision_get('Product Unit of Measure')
+ percent = float_round(1.0 / num_installment * 100, prec)
+ percent_last = 100 - (percent * (num_installment-1))
+ for i in range(num_installment):
+ this_installment = i+1
+ if num_installment == this_installment:
+ percent = percent_last
+ vals = {'installment': this_installment,
+ 'plan_date': installment_date,
+ 'invoice_type': 'installment',
+ 'percent': percent}
+ invoice_plans.append((0, 0, vals))
+ installment_date = self._next_date(installment_date,
+ interval, interval_type)
+ self.write({'invoice_plan_ids': invoice_plans})
+ return True
+
+ @api.multi
+ def remove_invoice_plan(self):
+ self.ensure_one()
+ self.invoice_plan_ids.unlink()
+ return True
+
+ @api.model
+ def _next_date(self, installment_date, interval, interval_type):
+ installment_date = fields.Date.from_string(installment_date)
+ if interval_type == 'month':
+ next_date = installment_date + relativedelta(months=+interval)
+ elif interval_type == 'year':
+ next_date = installment_date + relativedelta(years=+interval)
+ else:
+ next_date = installment_date + relativedelta(days=+interval)
+ next_date = fields.Date.to_string(next_date)
+ return next_date
+
+ @api.multi
+ def action_invoice_create(self):
+ self.ensure_one()
+ pre_inv = self.env['account.invoice'].new({
+ 'type': 'in_invoice',
+ 'purchase_id': self.id,
+ 'currency_id': self.currency_id.id,
+ 'company_id': self.company_id.id,
+ 'origin': self.name,
+ 'name': self.partner_ref or '',
+ 'comment': self.notes
+ })
+ pre_inv.purchase_order_change()
+ inv_data = pre_inv._convert_to_write(pre_inv._cache)
+ invoice = self.env['account.invoice'].create(inv_data)
+ invoice.compute_taxes()
+ if not invoice.invoice_line_ids:
+ raise UserError(
+ _("There is no invoiceable line. If a product has a"
+ "Delivered quantities invoicing policy, please make sure"
+ "that a quantity has been delivered."))
+ po_payment_term_id = invoice.payment_term_id.id
+ fp_invoice = invoice.fiscal_position_id
+ invoice._onchange_partner_id()
+ invoice.fiscal_position_id = fp_invoice
+ invoice.payment_term_id = po_payment_term_id
+ invoice.message_post_with_view(
+ 'mail.message_origin_link',
+ values={'self': invoice,
+ 'origin': self, },
+ subtype_id=self.env.ref('mail.mt_note').id)
+ invoice_plan_id = self._context.get('invoice_plan_id')
+ if invoice_plan_id:
+ plan = self.env['purchase.invoice.plan'].browse(invoice_plan_id)
+ plan._compute_new_invoice_quantity(invoice)
+ invoice.date_invoice = plan.plan_date
+ plan.invoice_ids += invoice
+ return invoice
+
+
+class PurchaseInvoicePlan(models.Model):
+ _name = 'purchase.invoice.plan'
+ _description = 'Invoice Planning Detail'
+ _order = 'installment'
+
+ purchase_id = fields.Many2one(
+ comodel_name='purchase.order',
+ string='Purchases Order',
+ index=True,
+ readonly=True,
+ ondelete='cascade',
+ )
+ partner_id = fields.Many2one(
+ comodel_name='res.partner',
+ string='Supplier',
+ related='purchase_id.partner_id',
+ store=True,
+ index=True,
+ )
+ state = fields.Selection(
+ [('draft', 'RFQ'),
+ ('sent', 'RFQ Sent'),
+ ('to approve', 'To Approve'),
+ ('purchase', 'Purchase Order'),
+ ('done', 'Locked'),
+ ('cancel', 'Cancelled'), ],
+ string='Status',
+ related='purchase_id.state',
+ store=True,
+ index=True,
+ )
+ installment = fields.Integer(
+ string='Installment',
+ )
+ plan_date = fields.Date(
+ string='Plan Date',
+ required=True,
+ )
+ invoice_type = fields.Selection(
+ [('installment', 'Installment')],
+ string='Type',
+ required=True,
+ default='installment',
+ )
+ percent = fields.Float(
+ string='Percent',
+ digits=dp.get_precision('Product Unit of Measure'),
+ help="This percent will be used to calculate new quantity"
+ )
+ invoice_ids = fields.Many2many(
+ 'account.invoice',
+ relation="purchase_invoice_plan_invoice_rel",
+ column1='plan_id',
+ column2='invoice_id',
+ string='Invoices',
+ readonly=True,
+ )
+ to_invoice = fields.Boolean(
+ string='Next Invoice',
+ compute='_compute_to_invoice',
+ help="If this line is ready to create new invoice",
+ )
+ invoiced = fields.Boolean(
+ string='Invoice Created',
+ compute='_compute_invoiced',
+ help="If this line already invoiced",
+ )
+
+ @api.multi
+ def _compute_to_invoice(self):
+ """ If any invoice is in draft/open/paid do not allow to create inv
+ Only if previous to_invoice is False, it is eligible to_invoice
+ """
+ for rec in self.sorted('installment'):
+ rec.to_invoice = False
+ if rec.purchase_id.state != 'purchase':
+ # Not confirmed, no to_invoice
+ continue
+ if not rec.invoiced:
+ rec.to_invoice = True
+ break
+
+ @api.multi
+ def _compute_invoiced(self):
+ for rec in self:
+ invoiced = rec.invoice_ids.filtered(
+ lambda l: l.state in ('draft', 'open', 'paid'))
+ rec.invoiced = invoiced and True or False
+
+ @api.multi
+ def _compute_new_invoice_quantity(self, invoice):
+ self.ensure_one()
+ percent = self.percent
+ for line in invoice.invoice_line_ids:
+ assert len(line.purchase_line_id) >= 0, \
+ 'No matched order line for invoice line'
+ order_line = fields.first(line.purchase_line_id)
+ plan_qty = order_line.product_qty * (percent/100)
+ prec = order_line.product_uom.rounding
+ if float_compare(plan_qty, line.quantity, prec) == 1:
+ raise ValidationError(
+ _('Plan quantity: %s, exceed invoiceable quantity: %s'
+ '\nProduct should be delivered before invoice') %
+ (plan_qty, line.quantity))
+ line.write({'quantity': plan_qty})
+ invoice.compute_taxes()
diff --git a/purchase_invoice_plan/readme/CONTRIBUTORS.rst b/purchase_invoice_plan/readme/CONTRIBUTORS.rst
new file mode 100644
index 00000000000..b461d809d66
--- /dev/null
+++ b/purchase_invoice_plan/readme/CONTRIBUTORS.rst
@@ -0,0 +1,2 @@
+* Kitti Upariphutthiphong
+* Rattapong Chokmasermkul
diff --git a/purchase_invoice_plan/readme/DESCRIPTION.rst b/purchase_invoice_plan/readme/DESCRIPTION.rst
new file mode 100644
index 00000000000..5d596ce4aa6
--- /dev/null
+++ b/purchase_invoice_plan/readme/DESCRIPTION.rst
@@ -0,0 +1,4 @@
+By standard feature, user can gradually create partial invoices, one by one and
+in step create invoice the standard call invoice.
+This module add ability to create invoices based on the predefined invoice plan,
+either all at once, or one by one.
diff --git a/purchase_invoice_plan/readme/USAGE.rst b/purchase_invoice_plan/readme/USAGE.rst
new file mode 100644
index 00000000000..9d62284fe2a
--- /dev/null
+++ b/purchase_invoice_plan/readme/USAGE.rst
@@ -0,0 +1,7 @@
+- Create new purchase quotation as per normal process
+- Select option "Use Invoice Plan", a new Invoice Plan tab will appear
+- Click on "=> Create Invoice Plan" link to open invoice planning wizard
+- Do plan for number of installment, start date and interval
+- Double check that each installment has correct plan percentage
+- After confirm purchases order, we have new option to "Create Bill by Plan"
+- User can create only next bill or create all bills at the same time
diff --git a/purchase_invoice_plan/security/ir.model.access.csv b/purchase_invoice_plan/security/ir.model.access.csv
new file mode 100644
index 00000000000..cea36980261
--- /dev/null
+++ b/purchase_invoice_plan/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_purchase_invoice_plan,access_purchase_invoice_plan,model_purchase_invoice_plan,,1,1,1,1
diff --git a/purchase_invoice_plan/static/description/index.html b/purchase_invoice_plan/static/description/index.html
new file mode 100644
index 00000000000..c153a0b72e4
--- /dev/null
+++ b/purchase_invoice_plan/static/description/index.html
@@ -0,0 +1,435 @@
+
+
+
+
+
+
+Purchase Invoice Plan
+
+
+
+
+
Purchase Invoice Plan
+
+
+
+
By standard feature, user can gradually create partial invoices, one by one and
+in step create invoice the standard call invoice.
+This module add ability to create invoices based on the predefined invoice plan,
+either all at once, or one by one.
Bugs are tracked on GitHub Issues.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+feedback.
+
Do not contact contributors directly about support or help with technical issues.
OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+ This view show all available invoice plan line for reporting purposes
+
+
+
+
+
+
+
diff --git a/purchase_invoice_plan/wizard/__init__.py b/purchase_invoice_plan/wizard/__init__.py
new file mode 100644
index 00000000000..41426745f08
--- /dev/null
+++ b/purchase_invoice_plan/wizard/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
+from . import purchase_create_invoice_plan
+from . import purchase_make_planned_invoice
diff --git a/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py b/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
new file mode 100644
index 00000000000..c1009146747
--- /dev/null
+++ b/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
@@ -0,0 +1,53 @@
+# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
+
+from odoo import models, fields, api, _
+from odoo.exceptions import ValidationError
+
+
+class PurchaseCreateInvoicePlan(models.TransientModel):
+ _name = 'purchase.create.invoice.plan'
+ _description = 'Fillig invoice planning criteria'
+
+ num_installment = fields.Integer(
+ string='Number of Installment',
+ default=0,
+ required=True,
+ )
+ installment_date = fields.Date(
+ string='Installment Date',
+ default=fields.Date.context_today,
+ required=True,
+ )
+ interval = fields.Integer(
+ string='Interval',
+ default=1,
+ required=True,
+ )
+ interval_type = fields.Selection(
+ [('day', 'Day'),
+ ('month', 'Month'),
+ ('year', 'Year')],
+ string='Interval Type',
+ default='month',
+ required=True,
+ )
+
+ @api.multi
+ @api.constrains('num_installment')
+ def _check_num_installment(self):
+ if self.num_installment <= 1:
+ raise ValidationError(_('Number Installment must greater than 1'))
+
+ @api.multi
+ def purchase_create_invoice_plan(self):
+ purchase = self.env['purchase.order'].\
+ browse(self._context.get('active_id'))
+ self.ensure_one()
+ purchase.create_invoice_plan(
+ self.num_installment,
+ self.installment_date,
+ self.interval,
+ self.interval_type,
+ )
+ return {'type': 'ir.actions.act_window_close'}
diff --git a/purchase_invoice_plan/wizard/purchase_create_invoice_plan_view.xml b/purchase_invoice_plan/wizard/purchase_create_invoice_plan_view.xml
new file mode 100644
index 00000000000..774e727e007
--- /dev/null
+++ b/purchase_invoice_plan/wizard/purchase_create_invoice_plan_view.xml
@@ -0,0 +1,48 @@
+
+
+
+ Create Invoice Plan
+ purchase.create.invoice.plan
+
+
+
+
+
+
+ Create Invoice Plan
+ ir.actions.act_window
+ purchase.create.invoice.plan
+ form
+ form
+ new
+
+
+
diff --git a/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
new file mode 100644
index 00000000000..efd9f644009
--- /dev/null
+++ b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
@@ -0,0 +1,22 @@
+# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
+
+from odoo import models, api
+
+
+class PurchaseAdvancePaymentInv(models.TransientModel):
+ _name = 'purchase.make.planned.invoice'
+ _description = 'Wizard when create invoice by plan'
+
+ @api.multi
+ def create_invoices_by_plan(self):
+ purchase = self.env['purchase.order'].\
+ browse(self._context.get('active_id'))
+ purchase.ensure_one()
+ invoice_plans = self._context.get('all_remain_invoices') and \
+ purchase.invoice_plan_ids.filtered(lambda l: not l.invoiced) or \
+ purchase.invoice_plan_ids.filtered('to_invoice')
+ for plan in invoice_plans.sorted('installment'):
+ purchase.with_context(invoice_plan_id=plan.id).\
+ action_invoice_create()
+ return {'type': 'ir.actions.act_window_close'}
diff --git a/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml b/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
new file mode 100644
index 00000000000..2591396fe29
--- /dev/null
+++ b/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
@@ -0,0 +1,41 @@
+
+
+ view.purchase.make.planned.invoice
+ purchase.make.planned.invoice
+
+
+
+
+
+
+ Invoice Order
+ ir.actions.act_window
+ purchase.make.planned.invoice
+ form
+ form
+ new
+
+
+
From c8f4ce16400f61d85ae3597b48eaa491593932f0 Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Tue, 15 Oct 2019 09:24:47 +0000
Subject: [PATCH 02/49] [UPD] Update purchase_invoice_plan.pot
---
.../i18n/purchase_invoice_plan.pot | 379 ++++++++++++++++++
1 file changed, 379 insertions(+)
create mode 100644 purchase_invoice_plan/i18n/purchase_invoice_plan.pot
diff --git a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
new file mode 100644
index 00000000000..f54663d91b9
--- /dev/null
+++ b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
@@ -0,0 +1,379 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * purchase_invoice_plan
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.purchase_order_form
+msgid "Are you sure to remove this invoice plan?"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,help:purchase_invoice_plan.field_purchase_order__ip_invoice_plan
+msgid "At least one invoice plan line pending to create invoice"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_make_planned_invoice
+msgid "Bill Purchase Order"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Bills Received"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_make_planned_invoice
+msgid "Bills will be created in draft for this installment\n"
+" so that you can review them before validation."
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_create_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_make_planned_invoice
+msgid "Cancel"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_make_planned_invoice
+msgid "Create All Remaining Bills"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.purchase_order_form
+msgid "Create Bill by Plan"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.actions.act_window,name:purchase_invoice_plan.action_purchase_create_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_create_invoice_plan
+msgid "Create Invoice Plan"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_make_planned_invoice
+msgid "Create Next Bill"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__create_uid
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__create_uid
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__create_date
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__create_date
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__create_date
+msgid "Created on"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: selection:purchase.create.invoice.plan,interval_type:0
+msgid "Day"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__display_name
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__display_name
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model,name:purchase_invoice_plan.model_purchase_create_invoice_plan
+msgid "Fillig invoice planning criteria"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Group By"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__id
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__id
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__id
+msgid "ID"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,help:purchase_invoice_plan.field_purchase_invoice_plan__invoiced
+msgid "If this line already invoiced"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,help:purchase_invoice_plan.field_purchase_invoice_plan__to_invoice
+msgid "If this line is ready to create new invoice"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__invoice_plan_ids
+msgid "Inovice Plan"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__installment
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+#: selection:purchase.invoice.plan,invoice_type:0
+msgid "Installment"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__installment_date
+msgid "Installment Date"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__interval
+msgid "Interval"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__interval_type
+msgid "Interval Type"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__invoiced
+msgid "Invoice Created"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.actions.act_window,name:purchase_invoice_plan.action_view_purchase_make_planned_invoice
+msgid "Invoice Order"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.purchase_order_form
+msgid "Invoice Plan"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__ip_invoice_plan
+msgid "Invoice Plan In Process"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model,name:purchase_invoice_plan.model_purchase_invoice_plan
+msgid "Invoice Planning Detail"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__invoice_ids
+msgid "Invoices"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan____last_update
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan____last_update
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__write_uid
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__write_uid
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__write_date
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__write_date
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: selection:purchase.create.invoice.plan,interval_type:0
+msgid "Month"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__to_invoice
+msgid "Next Invoice"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: code:addons/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py:40
+#, python-format
+msgid "Number Installment must greater than 1"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__num_installment
+msgid "Number of Installment"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__percent
+msgid "Percent"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__plan_date
+msgid "Plan Date"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: code:addons/purchase_invoice_plan/models/purchase.py:239
+#, python-format
+msgid "Plan quantity: %s, exceed invoiceable quantity: %s\n"
+"Product should be delivered before invoice"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: code:addons/purchase_invoice_plan/models/purchase.py:46
+#, python-format
+msgid "Please fill percentage for all invoice plan lines"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.actions.act_window,name:purchase_invoice_plan.action_purchase_invoice_plan
+#: model:ir.ui.menu,name:purchase_invoice_plan.menu_purchase_invoice_plan
+msgid "Purchase Invoice Plan"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model,name:purchase_invoice_plan.model_purchase_order
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Purchase Order"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Purchase Orders"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Purchase orders that have been invoiced."
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Purchase orders that include lines not invoiced."
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__purchase_id
+msgid "Purchases Order"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Quotations"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_form
+msgid "Related Bills"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Search Purchase Invoice Plan Lines"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__state
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Status"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__partner_id
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Supplier"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: code:addons/purchase_invoice_plan/models/purchase.py:116
+#, python-format
+msgid "There is no invoiceable line. If a product has aDelivered quantities invoicing policy, please make surethat a quantity has been delivered."
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,help:purchase_invoice_plan.field_purchase_invoice_plan__percent
+msgid "This percent will be used to calculate new quantity"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.actions.act_window,help:purchase_invoice_plan.action_purchase_invoice_plan
+msgid "This view show all available invoice plan line for reporting purposes"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_create_invoice_plan
+msgid "This wizard help you quickly create invoice plan."
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "To Approve"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__invoice_type
+msgid "Type"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__use_invoice_plan
+msgid "Use Invoice Plan"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: code:addons/purchase_invoice_plan/models/purchase.py:53
+#, python-format
+msgid "Use Invoice Plan selected, but no plan created"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.actions.act_window,help:purchase_invoice_plan.action_purchase_invoice_plan
+msgid "View purchase invoice plan lines"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
+msgid "Waiting Bills"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model,name:purchase_invoice_plan.model_purchase_make_planned_invoice
+msgid "Wizard when create invoice by plan"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: selection:purchase.create.invoice.plan,interval_type:0
+msgid "Year"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,help:purchase_invoice_plan.field_purchase_invoice_plan__partner_id
+msgid "You can find a vendor by its Name, TIN, Email or Internal Reference."
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.purchase_order_form
+msgid "⇒ Create Invoice Plan"
+msgstr ""
+
+#. module: purchase_invoice_plan
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.purchase_order_form
+msgid "⇒ Remove Invoice Plan"
+msgstr ""
+
From 0d32ab58f9d86ccaf2d77429c5dec06d740e75dc Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Tue, 15 Oct 2019 10:04:10 +0000
Subject: [PATCH 03/49] [UPD] README.rst
---
purchase_invoice_plan/README.rst | 93 +++++++++++++++++++
.../static/description/index.html | 19 ++--
2 files changed, 106 insertions(+), 6 deletions(-)
create mode 100644 purchase_invoice_plan/README.rst
diff --git a/purchase_invoice_plan/README.rst b/purchase_invoice_plan/README.rst
new file mode 100644
index 00000000000..9b90b773b60
--- /dev/null
+++ b/purchase_invoice_plan/README.rst
@@ -0,0 +1,93 @@
+=====================
+Purchase Invoice Plan
+=====================
+
+.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
+ :target: https://odoo-community.org/page/development-status
+ :alt: Alpha
+.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github
+ :target: https://github.com/OCA/purchase-workflow/tree/12.0/purchase_invoice_plan
+ :alt: OCA/purchase-workflow
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+ :target: https://translation.odoo-community.org/projects/purchase-workflow-12-0/purchase-workflow-12-0-purchase_invoice_plan
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
+ :target: https://runbot.odoo-community.org/runbot/142/12.0
+ :alt: Try me on Runbot
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
+
+By standard feature, user can gradually create partial invoices, one by one and
+in step create invoice the standard call invoice.
+This module add ability to create invoices based on the predefined invoice plan,
+either all at once, or one by one.
+
+.. IMPORTANT::
+ This is an alpha version, the data model and design can change at any time without warning.
+ Only for development or testing purpose, do not use in production.
+ `More details on development status `_
+
+**Table of contents**
+
+.. contents::
+ :local:
+
+Usage
+=====
+
+- Create new purchase quotation as per normal process
+- Select option "Use Invoice Plan", a new Invoice Plan tab will appear
+- Click on "=> Create Invoice Plan" link to open invoice planning wizard
+- Do plan for number of installment, start date and interval
+- Double check that each installment has correct plan percentage
+- After confirm purchases order, we have new option to "Create Bill by Plan"
+- User can create only next bill or create all bills at the same time
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues `_.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+`feedback `_.
+
+Do not contact contributors directly about support or help with technical issues.
+
+Credits
+=======
+
+Authors
+~~~~~~~
+
+* Ecosoft
+
+Contributors
+~~~~~~~~~~~~
+
+* Kitti Upariphutthiphong
+* Rattapong Chokmasermkul
+
+Maintainers
+~~~~~~~~~~~
+
+This module is maintained by the OCA.
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
+This module is part of the `OCA/purchase-workflow `_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/purchase_invoice_plan/static/description/index.html b/purchase_invoice_plan/static/description/index.html
index c153a0b72e4..a9b7670b59d 100644
--- a/purchase_invoice_plan/static/description/index.html
+++ b/purchase_invoice_plan/static/description/index.html
@@ -367,11 +367,17 @@
Purchase Invoice Plan
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
By standard feature, user can gradually create partial invoices, one by one and
in step create invoice the standard call invoice.
This module add ability to create invoices based on the predefined invoice plan,
either all at once, or one by one.
+
+
Important
+
This is an alpha version, the data model and design can change at any time without warning.
+Only for development or testing purpose, do not use in production.
+More details on development status
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-feedback.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-
Create Invoice Planir.actions.act_window
@@ -44,5 +40,4 @@
formnew
-
diff --git a/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
index efd9f644009..95a5d1f10dc 100644
--- a/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
+++ b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
@@ -1,22 +1,22 @@
# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
-from odoo import models, api
+from odoo import api, models
class PurchaseAdvancePaymentInv(models.TransientModel):
- _name = 'purchase.make.planned.invoice'
- _description = 'Wizard when create invoice by plan'
+ _name = "purchase.make.planned.invoice"
+ _description = "Wizard when create invoice by plan"
@api.multi
def create_invoices_by_plan(self):
- purchase = self.env['purchase.order'].\
- browse(self._context.get('active_id'))
+ purchase = self.env["purchase.order"].browse(self._context.get("active_id"))
purchase.ensure_one()
- invoice_plans = self._context.get('all_remain_invoices') and \
- purchase.invoice_plan_ids.filtered(lambda l: not l.invoiced) or \
- purchase.invoice_plan_ids.filtered('to_invoice')
- for plan in invoice_plans.sorted('installment'):
- purchase.with_context(invoice_plan_id=plan.id).\
- action_invoice_create()
- return {'type': 'ir.actions.act_window_close'}
+ invoice_plans = (
+ self._context.get("all_remain_invoices")
+ and purchase.invoice_plan_ids.filtered(lambda l: not l.invoiced)
+ or purchase.invoice_plan_ids.filtered("to_invoice")
+ )
+ for plan in invoice_plans.sorted("installment"):
+ purchase.with_context(invoice_plan_id=plan.id).action_invoice_create()
+ return {"type": "ir.actions.act_window_close"}
diff --git a/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml b/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
index 2591396fe29..1c6f85486fa 100644
--- a/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
+++ b/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
@@ -1,41 +1,41 @@
-
- view.purchase.make.planned.invoice
- purchase.make.planned.invoice
-
-
+
+
+
+ Invoice Order
+ ir.actions.act_window
+ purchase.make.planned.invoice
+ form
+ form
+ new
+
From a72eaf732e11a847499505eb716b5a3f43815966 Mon Sep 17 00:00:00 2001
From: Kitti U
Date: Wed, 8 Jul 2020 14:32:01 +0700
Subject: [PATCH 08/49] [MIG] purchase_invoice_plan
:100644 000000 9b90b773 00000000 D purchase_invoice_plan/README.rst
:100644 100644 9a68d442 051bb1da M purchase_invoice_plan/__manifest__.py
:100644 100644 8bb4c5d6 3da440c9 M purchase_invoice_plan/models/purchase.py
:100644 100644 d90eaa42 1c1deabc M purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
:100644 100644 326c1a0b dab7a93c M purchase_invoice_plan/wizard/purchase_create_invoice_plan_view.xml
:100644 100644 95a5d1f1 0883bce1 M purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
:100644 100644 1c6f8548 0bbbcd59 M purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
:000000 120000 00000000 71b680a3 A setup/purchase_invoice_plan/odoo/addons/purchase_invoice_plan
:000000 100644 00000000 28c57bb6 A setup/purchase_invoice_plan/setup.py
---
purchase_invoice_plan/README.rst | 93 -------------------
purchase_invoice_plan/__manifest__.py | 7 +-
purchase_invoice_plan/models/purchase.py | 61 ++++++------
.../tests/test_purchase_invoice_plan.py | 7 ++
.../wizard/purchase_create_invoice_plan.py | 2 -
.../purchase_create_invoice_plan_view.xml | 1 -
.../wizard/purchase_make_planned_invoice.py | 3 +-
.../purchase_make_planned_invoice_view.xml | 1 -
8 files changed, 39 insertions(+), 136 deletions(-)
delete mode 100644 purchase_invoice_plan/README.rst
diff --git a/purchase_invoice_plan/README.rst b/purchase_invoice_plan/README.rst
deleted file mode 100644
index 9b90b773b60..00000000000
--- a/purchase_invoice_plan/README.rst
+++ /dev/null
@@ -1,93 +0,0 @@
-=====================
-Purchase Invoice Plan
-=====================
-
-.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !! This file is generated by oca-gen-addon-readme !!
- !! changes will be overwritten. !!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
- :target: https://odoo-community.org/page/development-status
- :alt: Alpha
-.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
- :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
- :alt: License: AGPL-3
-.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github
- :target: https://github.com/OCA/purchase-workflow/tree/12.0/purchase_invoice_plan
- :alt: OCA/purchase-workflow
-.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/purchase-workflow-12-0/purchase-workflow-12-0-purchase_invoice_plan
- :alt: Translate me on Weblate
-.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/142/12.0
- :alt: Try me on Runbot
-
-|badge1| |badge2| |badge3| |badge4| |badge5|
-
-By standard feature, user can gradually create partial invoices, one by one and
-in step create invoice the standard call invoice.
-This module add ability to create invoices based on the predefined invoice plan,
-either all at once, or one by one.
-
-.. IMPORTANT::
- This is an alpha version, the data model and design can change at any time without warning.
- Only for development or testing purpose, do not use in production.
- `More details on development status `_
-
-**Table of contents**
-
-.. contents::
- :local:
-
-Usage
-=====
-
-- Create new purchase quotation as per normal process
-- Select option "Use Invoice Plan", a new Invoice Plan tab will appear
-- Click on "=> Create Invoice Plan" link to open invoice planning wizard
-- Do plan for number of installment, start date and interval
-- Double check that each installment has correct plan percentage
-- After confirm purchases order, we have new option to "Create Bill by Plan"
-- User can create only next bill or create all bills at the same time
-
-Bug Tracker
-===========
-
-Bugs are tracked on `GitHub Issues `_.
-In case of trouble, please check there if your issue has already been reported.
-If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
-
-Do not contact contributors directly about support or help with technical issues.
-
-Credits
-=======
-
-Authors
-~~~~~~~
-
-* Ecosoft
-
-Contributors
-~~~~~~~~~~~~
-
-* Kitti Upariphutthiphong
-* Rattapong Chokmasermkul
-
-Maintainers
-~~~~~~~~~~~
-
-This module is maintained by the OCA.
-
-.. image:: https://odoo-community.org/logo.png
- :alt: Odoo Community Association
- :target: https://odoo-community.org
-
-OCA, or the Odoo Community Association, is a nonprofit organization whose
-mission is to support the collaborative development of Odoo features and
-promote its widespread use.
-
-This module is part of the `OCA/purchase-workflow `_ project on GitHub.
-
-You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index 9a68d442168..e56c484a347 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,12 +4,12 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "12.0.1.0.1",
+ "version": "13.0.1.0.0",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow/",
"category": "Purchase",
- "depends": ["account", "purchase_open_qty", "purchase_stock",],
+ "depends": ["purchase_open_qty", "purchase_stock"],
"data": [
"security/ir.model.access.csv",
"wizard/purchase_create_invoice_plan_view.xml",
@@ -17,5 +17,6 @@
"views/purchase_view.xml",
],
"installable": True,
- "development_status": "alpha",
+ "maintainers": ["kittiu"],
+ "development_status": "Alpha",
}
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 8bb4c5d6263..78f3ffa911d 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -7,8 +7,6 @@
from odoo.exceptions import UserError, ValidationError
from odoo.tools.float_utils import float_compare, float_round
-from odoo.addons import decimal_precision as dp
-
class PurchaseOrder(models.Model):
_inherit = "purchase.order"
@@ -16,7 +14,7 @@ class PurchaseOrder(models.Model):
invoice_plan_ids = fields.One2many(
comodel_name="purchase.invoice.plan",
inverse_name="purchase_id",
- string="Inovice Plan",
+ string="Invoice Plan",
copy=False,
readonly=True,
states={"draft": [("readonly", False)]},
@@ -30,7 +28,6 @@ class PurchaseOrder(models.Model):
help="At least one invoice plan line pending to create invoice",
)
- @api.multi
def _compute_ip_invoice_plan(self):
for rec in self:
rec.ip_invoice_plan = (
@@ -48,13 +45,11 @@ def _check_invoice_plan(self):
_("Please fill percentage for all invoice plan lines")
)
- @api.multi
def action_confirm(self):
if self.filtered(lambda r: r.use_invoice_plan and not r.invoice_plan_ids):
raise UserError(_("Use Invoice Plan selected, but no plan created"))
return super().action_confirm()
- @api.multi
def create_invoice_plan(
self, num_installment, installment_date, interval, interval_type
):
@@ -82,7 +77,6 @@ def create_invoice_plan(
self.write({"invoice_plan_ids": invoice_plans})
return True
- @api.multi
def remove_invoice_plan(self):
self.ensure_one()
self.invoice_plan_ids.unlink()
@@ -100,24 +94,31 @@ def _next_date(self, installment_date, interval, interval_type):
next_date = fields.Date.to_string(next_date)
return next_date
- @api.multi
def action_invoice_create(self):
- self.ensure_one()
- pre_inv = self.env["account.invoice"].new(
+ journal = (
+ self.env["account.move"]
+ .with_context(
+ default_type="in_invoice", default_currency_id=self.currency_id.id
+ )
+ ._get_default_journal()
+ )
+ pre_inv = self.env["account.move"].new(
{
"type": "in_invoice",
"purchase_id": self.id,
+ "journal_id": journal.id,
"currency_id": self.currency_id.id,
"company_id": self.company_id.id,
- "origin": self.name,
- "name": self.partner_ref or "",
- "comment": self.notes,
+ "invoice_origin": self.name,
+ "ref": self.partner_ref or "",
+ "narration": self.notes,
+ "fiscal_position_id": self.fiscal_position_id.id,
+ "invoice_payment_term_id": self.payment_term_id.id,
}
)
- pre_inv.purchase_order_change()
+ pre_inv._onchange_purchase_auto_complete()
inv_data = pre_inv._convert_to_write(pre_inv._cache)
- invoice = self.env["account.invoice"].create(inv_data)
- invoice.compute_taxes()
+ invoice = self.env["account.move"].create(inv_data)
if not invoice.invoice_line_ids:
raise UserError(
_(
@@ -126,14 +127,10 @@ def action_invoice_create(self):
"that a quantity has been delivered."
)
)
- po_payment_term_id = invoice.payment_term_id.id
- fp_invoice = invoice.fiscal_position_id
invoice._onchange_partner_id()
- invoice.fiscal_position_id = fp_invoice
- invoice.payment_term_id = po_payment_term_id
invoice.message_post_with_view(
"mail.message_origin_link",
- values={"self": invoice, "origin": self,},
+ values={"self": invoice, "origin": self},
subtype_id=self.env.ref("mail.mt_note").id,
)
invoice_plan_id = self._context.get("invoice_plan_id")
@@ -165,7 +162,7 @@ class PurchaseInvoicePlan(models.Model):
index=True,
)
state = fields.Selection(
- [
+ selection=[
("draft", "RFQ"),
("sent", "RFQ Sent"),
("to approve", "To Approve"),
@@ -181,21 +178,21 @@ class PurchaseInvoicePlan(models.Model):
installment = fields.Integer(string="Installment",)
plan_date = fields.Date(string="Plan Date", required=True,)
invoice_type = fields.Selection(
- [("installment", "Installment")],
+ selection=[("installment", "Installment")],
string="Type",
required=True,
default="installment",
)
percent = fields.Float(
string="Percent",
- digits=dp.get_precision("Product Unit of Measure"),
+ digits="Product Unit of Measure",
help="This percent will be used to calculate new quantity",
)
invoice_ids = fields.Many2many(
- "account.invoice",
+ comodel_name="account.move",
relation="purchase_invoice_plan_invoice_rel",
column1="plan_id",
- column2="invoice_id",
+ column2="move_id",
string="Invoices",
readonly=True,
)
@@ -210,29 +207,26 @@ class PurchaseInvoicePlan(models.Model):
help="If this line already invoiced",
)
- @api.multi
def _compute_to_invoice(self):
""" If any invoice is in draft/open/paid do not allow to create inv
Only if previous to_invoice is False, it is eligible to_invoice
"""
- for rec in self.sorted("installment"):
+ for rec in self:
rec.to_invoice = False
+ for rec in self.sorted("installment"):
if rec.purchase_id.state != "purchase":
- # Not confirmed, no to_invoice
continue
if not rec.invoiced:
rec.to_invoice = True
break
- @api.multi
def _compute_invoiced(self):
for rec in self:
invoiced = rec.invoice_ids.filtered(
- lambda l: l.state in ("draft", "open", "paid")
+ lambda l: l.state in ("draft", "posted")
)
rec.invoiced = invoiced and True or False
- @api.multi
def _compute_new_invoice_quantity(self, invoice):
self.ensure_one()
percent = self.percent
@@ -251,8 +245,7 @@ def _compute_new_invoice_quantity(self, invoice):
)
% (plan_qty, line.quantity)
)
- line.write({"quantity": plan_qty})
- invoice.compute_taxes()
+ line.with_context(check_move_validity=False).write({"quantity": plan_qty})
@api.model
def _get_plan_qty(self, order_line, percent):
diff --git a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
index 298f812bc1c..4a0c057785f 100644
--- a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
+++ b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
@@ -99,6 +99,13 @@ def test_error(self):
"active_ids": [self.test_po_product.id],
"all_remain_invoices": True,
}
+ # ValidationError Number of Installment <= 1
+ with self.assertRaises(ValidationError) as e:
+ with Form(self.PurchaseInvoicePlan) as p:
+ p.num_installment = 0
+ p.save()
+ error_message = "Number Installment must greater than 1"
+ self.assertEqual(e.exception.name, error_message)
# Create purchase plan
with Form(self.PurchaseInvoicePlan) as p:
p.num_installment = 5
diff --git a/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py b/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
index d90eaa42913..1c1deabcadd 100644
--- a/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
+++ b/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
@@ -23,13 +23,11 @@ class PurchaseCreateInvoicePlan(models.TransientModel):
required=True,
)
- @api.multi
@api.constrains("num_installment")
def _check_num_installment(self):
if self.num_installment <= 1:
raise ValidationError(_("Number Installment must greater than 1"))
- @api.multi
def purchase_create_invoice_plan(self):
purchase = self.env["purchase.order"].browse(self._context.get("active_id"))
self.ensure_one()
diff --git a/purchase_invoice_plan/wizard/purchase_create_invoice_plan_view.xml b/purchase_invoice_plan/wizard/purchase_create_invoice_plan_view.xml
index 326c1a0b73d..dab7a93c2c9 100644
--- a/purchase_invoice_plan/wizard/purchase_create_invoice_plan_view.xml
+++ b/purchase_invoice_plan/wizard/purchase_create_invoice_plan_view.xml
@@ -36,7 +36,6 @@
Create Invoice Planir.actions.act_windowpurchase.create.invoice.plan
- formformnew
diff --git a/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
index 95a5d1f10dc..0883bce1323 100644
--- a/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
+++ b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
@@ -1,14 +1,13 @@
# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
-from odoo import api, models
+from odoo import models
class PurchaseAdvancePaymentInv(models.TransientModel):
_name = "purchase.make.planned.invoice"
_description = "Wizard when create invoice by plan"
- @api.multi
def create_invoices_by_plan(self):
purchase = self.env["purchase.order"].browse(self._context.get("active_id"))
purchase.ensure_one()
diff --git a/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml b/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
index 1c6f85486fa..0bbbcd5920d 100644
--- a/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
+++ b/purchase_invoice_plan/wizard/purchase_make_planned_invoice_view.xml
@@ -34,7 +34,6 @@
Invoice Orderir.actions.act_windowpurchase.make.planned.invoice
- formformnew
From 9eb19b0f1b6e610542ca0e4bdfa38d696d36bcf1 Mon Sep 17 00:00:00 2001
From: Surachet Saejueng
Date: Thu, 19 Nov 2020 04:35:20 +0000
Subject: [PATCH 09/49] [IMP] purchase_invoice_plan: black, isort, prettier
---
purchase_invoice_plan/README.rst | 93 +++++++++++++++++++
purchase_invoice_plan/__manifest__.py | 2 +-
purchase_invoice_plan/models/purchase.py | 17 +++-
.../wizard/purchase_create_invoice_plan.py | 14 ++-
4 files changed, 117 insertions(+), 9 deletions(-)
create mode 100644 purchase_invoice_plan/README.rst
diff --git a/purchase_invoice_plan/README.rst b/purchase_invoice_plan/README.rst
new file mode 100644
index 00000000000..9b90b773b60
--- /dev/null
+++ b/purchase_invoice_plan/README.rst
@@ -0,0 +1,93 @@
+=====================
+Purchase Invoice Plan
+=====================
+
+.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
+ :target: https://odoo-community.org/page/development-status
+ :alt: Alpha
+.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github
+ :target: https://github.com/OCA/purchase-workflow/tree/12.0/purchase_invoice_plan
+ :alt: OCA/purchase-workflow
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+ :target: https://translation.odoo-community.org/projects/purchase-workflow-12-0/purchase-workflow-12-0-purchase_invoice_plan
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
+ :target: https://runbot.odoo-community.org/runbot/142/12.0
+ :alt: Try me on Runbot
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
+
+By standard feature, user can gradually create partial invoices, one by one and
+in step create invoice the standard call invoice.
+This module add ability to create invoices based on the predefined invoice plan,
+either all at once, or one by one.
+
+.. IMPORTANT::
+ This is an alpha version, the data model and design can change at any time without warning.
+ Only for development or testing purpose, do not use in production.
+ `More details on development status `_
+
+**Table of contents**
+
+.. contents::
+ :local:
+
+Usage
+=====
+
+- Create new purchase quotation as per normal process
+- Select option "Use Invoice Plan", a new Invoice Plan tab will appear
+- Click on "=> Create Invoice Plan" link to open invoice planning wizard
+- Do plan for number of installment, start date and interval
+- Double check that each installment has correct plan percentage
+- After confirm purchases order, we have new option to "Create Bill by Plan"
+- User can create only next bill or create all bills at the same time
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues `_.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+`feedback `_.
+
+Do not contact contributors directly about support or help with technical issues.
+
+Credits
+=======
+
+Authors
+~~~~~~~
+
+* Ecosoft
+
+Contributors
+~~~~~~~~~~~~
+
+* Kitti Upariphutthiphong
+* Rattapong Chokmasermkul
+
+Maintainers
+~~~~~~~~~~~
+
+This module is maintained by the OCA.
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
+This module is part of the `OCA/purchase-workflow `_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index e56c484a347..7c8556c0f11 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -7,7 +7,7 @@
"version": "13.0.1.0.0",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
- "website": "https://github.com/OCA/purchase-workflow/",
+ "website": "https://github.com/OCA/purchase-workflow",
"category": "Purchase",
"depends": ["purchase_open_qty", "purchase_stock"],
"data": [
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 78f3ffa911d..c27911b49dc 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -20,7 +20,9 @@ class PurchaseOrder(models.Model):
states={"draft": [("readonly", False)]},
)
use_invoice_plan = fields.Boolean(
- string="Use Invoice Plan", default=False, copy=False,
+ string="Use Invoice Plan",
+ default=False,
+ copy=False,
)
ip_invoice_plan = fields.Boolean(
string="Invoice Plan In Process",
@@ -175,8 +177,13 @@ class PurchaseInvoicePlan(models.Model):
store=True,
index=True,
)
- installment = fields.Integer(string="Installment",)
- plan_date = fields.Date(string="Plan Date", required=True,)
+ installment = fields.Integer(
+ string="Installment",
+ )
+ plan_date = fields.Date(
+ string="Plan Date",
+ required=True,
+ )
invoice_type = fields.Selection(
selection=[("installment", "Installment")],
string="Type",
@@ -208,8 +215,8 @@ class PurchaseInvoicePlan(models.Model):
)
def _compute_to_invoice(self):
- """ If any invoice is in draft/open/paid do not allow to create inv
- Only if previous to_invoice is False, it is eligible to_invoice
+ """If any invoice is in draft/open/paid do not allow to create inv
+ Only if previous to_invoice is False, it is eligible to_invoice
"""
for rec in self:
rec.to_invoice = False
diff --git a/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py b/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
index 1c1deabcadd..11dc6098c90 100644
--- a/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
+++ b/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
@@ -10,12 +10,20 @@ class PurchaseCreateInvoicePlan(models.TransientModel):
_description = "Fillig invoice planning criteria"
num_installment = fields.Integer(
- string="Number of Installment", default=0, required=True,
+ string="Number of Installment",
+ default=0,
+ required=True,
)
installment_date = fields.Date(
- string="Installment Date", default=fields.Date.context_today, required=True,
+ string="Installment Date",
+ default=fields.Date.context_today,
+ required=True,
+ )
+ interval = fields.Integer(
+ string="Interval",
+ default=1,
+ required=True,
)
- interval = fields.Integer(string="Interval", default=1, required=True,)
interval_type = fields.Selection(
[("day", "Day"), ("month", "Month"), ("year", "Year")],
string="Interval Type",
From 25d67d4cfcbcd5b8dca0ee50908edfed23fccd7e Mon Sep 17 00:00:00 2001
From: Surachet Saejueng
Date: Thu, 19 Nov 2020 08:29:15 +0000
Subject: [PATCH 10/49] [MIG] purchase_invoice_plan: Migration to 14.0
---
purchase_invoice_plan/__manifest__.py | 2 +-
purchase_invoice_plan/models/purchase.py | 20 +++++++++----------
.../security/ir.model.access.csv | 2 ++
.../tests/test_purchase_invoice_plan.py | 8 ++++----
purchase_invoice_plan/views/purchase_view.xml | 6 +++---
5 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index 7c8556c0f11..ab305ea3a72 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "13.0.1.0.0",
+ "version": "14.0.1.0.0",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow",
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index c27911b49dc..ffd8033ce8d 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -100,13 +100,15 @@ def action_invoice_create(self):
journal = (
self.env["account.move"]
.with_context(
- default_type="in_invoice", default_currency_id=self.currency_id.id
+ default_type="in_invoice",
+ default_currency_id=self.currency_id.id,
+ default_company_id=self.env.user.company_id.id,
)
._get_default_journal()
)
pre_inv = self.env["account.move"].new(
{
- "type": "in_invoice",
+ "move_type": "in_invoice",
"purchase_id": self.id,
"journal_id": journal.id,
"currency_id": self.currency_id.id,
@@ -139,7 +141,7 @@ def action_invoice_create(self):
if invoice_plan_id:
plan = self.env["purchase.invoice.plan"].browse(invoice_plan_id)
plan._compute_new_invoice_quantity(invoice)
- invoice.date_invoice = plan.plan_date
+ invoice.invoice_date = plan.plan_date
plan.invoice_ids += invoice
return invoice
@@ -164,14 +166,6 @@ class PurchaseInvoicePlan(models.Model):
index=True,
)
state = fields.Selection(
- selection=[
- ("draft", "RFQ"),
- ("sent", "RFQ Sent"),
- ("to approve", "To Approve"),
- ("purchase", "Purchase Order"),
- ("done", "Locked"),
- ("cancel", "Cancelled"),
- ],
string="Status",
related="purchase_id.state",
store=True,
@@ -207,13 +201,16 @@ class PurchaseInvoicePlan(models.Model):
string="Next Invoice",
compute="_compute_to_invoice",
help="If this line is ready to create new invoice",
+ store=True,
)
invoiced = fields.Boolean(
string="Invoice Created",
compute="_compute_invoiced",
help="If this line already invoiced",
+ store=True,
)
+ @api.depends("purchase_id.state", "purchase_id.invoice_plan_ids.invoiced")
def _compute_to_invoice(self):
"""If any invoice is in draft/open/paid do not allow to create inv
Only if previous to_invoice is False, it is eligible to_invoice
@@ -227,6 +224,7 @@ def _compute_to_invoice(self):
rec.to_invoice = True
break
+ @api.depends("invoice_ids.state")
def _compute_invoiced(self):
for rec in self:
invoiced = rec.invoice_ids.filtered(
diff --git a/purchase_invoice_plan/security/ir.model.access.csv b/purchase_invoice_plan/security/ir.model.access.csv
index cea36980261..4bae5339c41 100644
--- a/purchase_invoice_plan/security/ir.model.access.csv
+++ b/purchase_invoice_plan/security/ir.model.access.csv
@@ -1,2 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_purchase_invoice_plan,access_purchase_invoice_plan,model_purchase_invoice_plan,,1,1,1,1
+access_purchase_create_invoice_plan,access_purchase_create_invoice_plan,model_purchase_create_invoice_plan,,1,1,1,1
+access_purchase_make_planned_invoice,access_purchase_make_planned_invoice,model_purchase_make_planned_invoice,,1,1,1,1
diff --git a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
index 4a0c057785f..9a000898fe1 100644
--- a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
+++ b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
@@ -76,7 +76,7 @@ def test_invoice_plan(self):
# Receive all products
receive = self.test_po_product.picking_ids.filtered(lambda l: l.state != "done")
receive.move_ids_without_package.quantity_done = 10.0
- receive.action_done()
+ receive._action_done()
purchase_create = self.env["purchase.make.planned.invoice"].create({})
purchase_create.with_context(ctx).create_invoices_by_plan()
@@ -105,7 +105,7 @@ def test_error(self):
p.num_installment = 0
p.save()
error_message = "Number Installment must greater than 1"
- self.assertEqual(e.exception.name, error_message)
+ self.assertEqual(e.exception.args[0], error_message)
# Create purchase plan
with Form(self.PurchaseInvoicePlan) as p:
p.num_installment = 5
@@ -116,7 +116,7 @@ def test_error(self):
# Receive product 1 unit
receive = self.test_po_product.picking_ids.filtered(lambda l: l.state != "done")
receive.move_ids_without_package.quantity_done = 1.0
- receive.action_done()
+ receive._action_done()
# ValidationError Create all invoice plan - Receive < Invoice require
purchase_create = self.env["purchase.make.planned.invoice"].create({})
with self.assertRaises(ValidationError) as e:
@@ -125,4 +125,4 @@ def test_error(self):
"Plan quantity: 2.0, exceed invoiceable quantity: 1.0"
"\nProduct should be delivered before invoice"
)
- self.assertEqual(e.exception.name, error_message)
+ self.assertEqual(e.exception.args[0], error_message)
diff --git a/purchase_invoice_plan/views/purchase_view.xml b/purchase_invoice_plan/views/purchase_view.xml
index dfdc87039b9..eb56d24b680 100644
--- a/purchase_invoice_plan/views/purchase_view.xml
+++ b/purchase_invoice_plan/views/purchase_view.xml
@@ -49,7 +49,7 @@
-
+
From 7cc4a6ab06797a9e501c03e2d78e42db70c99fcf Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Thu, 14 Jan 2021 23:18:00 +0000
Subject: [PATCH 11/49] [UPD] Update purchase_invoice_plan.pot
---
.../i18n/purchase_invoice_plan.pot | 44 ++++++++++---------
1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
index f54663d91b9..e088a11b0ef 100644
--- a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
+++ b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
@@ -1,12 +1,12 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
-# * purchase_invoice_plan
+# * purchase_invoice_plan
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 12.0\n"
+"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
-"Last-Translator: <>\n"
+"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -35,7 +35,8 @@ msgstr ""
#. module: purchase_invoice_plan
#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_make_planned_invoice
-msgid "Bills will be created in draft for this installment\n"
+msgid ""
+"Bills will be created in draft for this installment\n"
" so that you can review them before validation."
msgstr ""
@@ -81,7 +82,7 @@ msgid "Created on"
msgstr ""
#. module: purchase_invoice_plan
-#: selection:purchase.create.invoice.plan,interval_type:0
+#: model:ir.model.fields.selection,name:purchase_invoice_plan.selection__purchase_create_invoice_plan__interval_type__day
msgid "Day"
msgstr ""
@@ -89,6 +90,7 @@ msgstr ""
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__display_name
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__display_name
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__display_name
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__display_name
msgid "Display Name"
msgstr ""
@@ -106,6 +108,7 @@ msgstr ""
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__id
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__id
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__id
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__id
msgid "ID"
msgstr ""
@@ -119,15 +122,10 @@ msgstr ""
msgid "If this line is ready to create new invoice"
msgstr ""
-#. module: purchase_invoice_plan
-#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__invoice_plan_ids
-msgid "Inovice Plan"
-msgstr ""
-
#. module: purchase_invoice_plan
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__installment
+#: model:ir.model.fields.selection,name:purchase_invoice_plan.selection__purchase_invoice_plan__invoice_type__installment
#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_filter
-#: selection:purchase.invoice.plan,invoice_type:0
msgid "Installment"
msgstr ""
@@ -157,6 +155,7 @@ msgid "Invoice Order"
msgstr ""
#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__invoice_plan_ids
#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.purchase_order_form
msgid "Invoice Plan"
msgstr ""
@@ -180,6 +179,7 @@ msgstr ""
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan____last_update
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan____last_update
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice____last_update
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order____last_update
msgid "Last Modified on"
msgstr ""
@@ -198,7 +198,7 @@ msgid "Last Updated on"
msgstr ""
#. module: purchase_invoice_plan
-#: selection:purchase.create.invoice.plan,interval_type:0
+#: model:ir.model.fields.selection,name:purchase_invoice_plan.selection__purchase_create_invoice_plan__interval_type__month
msgid "Month"
msgstr ""
@@ -208,7 +208,7 @@ msgid "Next Invoice"
msgstr ""
#. module: purchase_invoice_plan
-#: code:addons/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py:40
+#: code:addons/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py:0
#, python-format
msgid "Number Installment must greater than 1"
msgstr ""
@@ -229,14 +229,15 @@ msgid "Plan Date"
msgstr ""
#. module: purchase_invoice_plan
-#: code:addons/purchase_invoice_plan/models/purchase.py:239
+#: code:addons/purchase_invoice_plan/models/purchase.py:0
#, python-format
-msgid "Plan quantity: %s, exceed invoiceable quantity: %s\n"
+msgid ""
+"Plan quantity: %s, exceed invoiceable quantity: %s\n"
"Product should be delivered before invoice"
msgstr ""
#. module: purchase_invoice_plan
-#: code:addons/purchase_invoice_plan/models/purchase.py:46
+#: code:addons/purchase_invoice_plan/models/purchase.py:0
#, python-format
msgid "Please fill percentage for all invoice plan lines"
msgstr ""
@@ -301,9 +302,11 @@ msgid "Supplier"
msgstr ""
#. module: purchase_invoice_plan
-#: code:addons/purchase_invoice_plan/models/purchase.py:116
+#: code:addons/purchase_invoice_plan/models/purchase.py:0
#, python-format
-msgid "There is no invoiceable line. If a product has aDelivered quantities invoicing policy, please make surethat a quantity has been delivered."
+msgid ""
+"There is no invoiceable line. If a product has aDelivered quantities "
+"invoicing policy, please make surethat a quantity has been delivered."
msgstr ""
#. module: purchase_invoice_plan
@@ -337,7 +340,7 @@ msgid "Use Invoice Plan"
msgstr ""
#. module: purchase_invoice_plan
-#: code:addons/purchase_invoice_plan/models/purchase.py:53
+#: code:addons/purchase_invoice_plan/models/purchase.py:0
#, python-format
msgid "Use Invoice Plan selected, but no plan created"
msgstr ""
@@ -358,7 +361,7 @@ msgid "Wizard when create invoice by plan"
msgstr ""
#. module: purchase_invoice_plan
-#: selection:purchase.create.invoice.plan,interval_type:0
+#: model:ir.model.fields.selection,name:purchase_invoice_plan.selection__purchase_create_invoice_plan__interval_type__year
msgid "Year"
msgstr ""
@@ -376,4 +379,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.purchase_order_form
msgid "⇒ Remove Invoice Plan"
msgstr ""
-
From d0fd21ffd961d206ce51c364b6b914082f7e001e Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 14 Jan 2021 23:32:46 +0000
Subject: [PATCH 12/49] [UPD] README.rst
---
purchase_invoice_plan/README.rst | 20 +++++++++++++------
.../static/description/index.html | 8 +++++---
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/purchase_invoice_plan/README.rst b/purchase_invoice_plan/README.rst
index 9b90b773b60..1ef8f5cac6c 100644
--- a/purchase_invoice_plan/README.rst
+++ b/purchase_invoice_plan/README.rst
@@ -14,13 +14,13 @@ Purchase Invoice Plan
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github
- :target: https://github.com/OCA/purchase-workflow/tree/12.0/purchase_invoice_plan
+ :target: https://github.com/OCA/purchase-workflow/tree/14.0/purchase_invoice_plan
:alt: OCA/purchase-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/purchase-workflow-12-0/purchase-workflow-12-0-purchase_invoice_plan
+ :target: https://translation.odoo-community.org/projects/purchase-workflow-14-0/purchase-workflow-14-0-purchase_invoice_plan
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/142/12.0
+ :target: https://runbot.odoo-community.org/runbot/142/14.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -28,7 +28,7 @@ Purchase Invoice Plan
By standard feature, user can gradually create partial invoices, one by one and
in step create invoice the standard call invoice.
This module add ability to create invoices based on the predefined invoice plan,
-either all at once, or one by one.
+either all at once, or one by one.
.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
@@ -57,7 +57,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -88,6 +88,14 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-This module is part of the `OCA/purchase-workflow `_ project on GitHub.
+.. |maintainer-kittiu| image:: https://github.com/kittiu.png?size=40px
+ :target: https://github.com/kittiu
+ :alt: kittiu
+
+Current `maintainer `__:
+
+|maintainer-kittiu|
+
+This module is part of the `OCA/purchase-workflow `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/purchase_invoice_plan/static/description/index.html b/purchase_invoice_plan/static/description/index.html
index a9b7670b59d..2e35c38c448 100644
--- a/purchase_invoice_plan/static/description/index.html
+++ b/purchase_invoice_plan/static/description/index.html
@@ -367,7 +367,7 @@
Purchase Invoice Plan
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
By standard feature, user can gradually create partial invoices, one by one and
in step create invoice the standard call invoice.
This module add ability to create invoices based on the predefined invoice plan,
@@ -408,7 +408,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-feedback.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
From 1fd9b04f51075011f86b795673903caa7ae7ad7e Mon Sep 17 00:00:00 2001
From: Denis Roussel
Date: Wed, 7 Apr 2021 08:31:49 +0200
Subject: [PATCH 13/49] [14.0][FIX] purchase_invoice_plan: Fix default journal
type
---
purchase_invoice_plan/models/purchase.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index ffd8033ce8d..24898669b75 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -100,7 +100,7 @@ def action_invoice_create(self):
journal = (
self.env["account.move"]
.with_context(
- default_type="in_invoice",
+ default_move_type="in_invoice",
default_currency_id=self.currency_id.id,
default_company_id=self.env.user.company_id.id,
)
From fe0ed4b61760518308080a6b5e59287be00373a6 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Wed, 7 Apr 2021 10:01:46 +0000
Subject: [PATCH 14/49] purchase_invoice_plan 14.0.1.0.1
---
purchase_invoice_plan/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index ab305ea3a72..a78c5639da3 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "14.0.1.0.0",
+ "version": "14.0.1.0.1",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow",
From 3788ed7c47ec1a136474bbb91ad17b04f07c5eec Mon Sep 17 00:00:00 2001
From: Kitti U
Date: Wed, 19 May 2021 21:23:24 +0700
Subject: [PATCH 15/49] [14.0][IMP] purchase_invoice_plan, better last invoice
computation
---
purchase_invoice_plan/models/purchase.py | 53 ++++++++++++++++--------
1 file changed, 36 insertions(+), 17 deletions(-)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 24898669b75..8ce8d2eeb13 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -141,7 +141,12 @@ def action_invoice_create(self):
if invoice_plan_id:
plan = self.env["purchase.invoice.plan"].browse(invoice_plan_id)
plan._compute_new_invoice_quantity(invoice)
- invoice.invoice_date = plan.plan_date
+ invoice.write(
+ {
+ "date": plan.plan_date,
+ "invoice_date": plan.plan_date,
+ }
+ )
plan.invoice_ids += invoice
return invoice
@@ -184,6 +189,11 @@ class PurchaseInvoicePlan(models.Model):
required=True,
default="installment",
)
+ last = fields.Boolean(
+ string="Last Installment",
+ compute="_compute_last",
+ help="Last installment will create invoice use remaining amount",
+ )
percent = fields.Float(
string="Percent",
digits="Product Unit of Measure",
@@ -232,25 +242,34 @@ def _compute_invoiced(self):
)
rec.invoiced = invoiced and True or False
- def _compute_new_invoice_quantity(self, invoice):
+ def _compute_last(self):
+ for rec in self:
+ last = max(rec.purchase_id.invoice_plan_ids.mapped("installment"))
+ rec.last = rec.installment == last
+
+ def _compute_new_invoice_quantity(self, invoice_move):
self.ensure_one()
+ if self.last: # For last install, let the system do the calc.
+ return
percent = self.percent
- for line in invoice.invoice_line_ids:
- assert (
- len(line.purchase_line_id) >= 0
- ), "No matched order line for invoice line"
- order_line = fields.first(line.purchase_line_id)
- plan_qty = self._get_plan_qty(order_line, percent)
- prec = order_line.product_uom.rounding
- if float_compare(abs(plan_qty), abs(line.quantity), prec) == 1:
- raise ValidationError(
- _(
- "Plan quantity: %s, exceed invoiceable quantity: %s"
- "\nProduct should be delivered before invoice"
- )
- % (plan_qty, line.quantity)
+ move = invoice_move.with_context({"check_move_validity": False})
+ for line in move.invoice_line_ids:
+ self._update_new_quantity(line, percent)
+ move._move_autocomplete_invoice_lines_values() # recompute dr/cr
+
+ def _update_new_quantity(self, line, percent):
+ """ Hook function """
+ plan_qty = self._get_plan_qty(line.purchase_line_id, percent)
+ prec = line.purchase_line_id.product_uom.rounding
+ if float_compare(abs(plan_qty), abs(line.quantity), prec) == 1:
+ raise ValidationError(
+ _(
+ "Plan quantity: %s, exceed invoiceable quantity: %s"
+ "\nProduct should be delivered before invoice"
)
- line.with_context(check_move_validity=False).write({"quantity": plan_qty})
+ % (plan_qty, line.quantity)
+ )
+ line.write({"quantity": plan_qty})
@api.model
def _get_plan_qty(self, order_line, percent):
From 2d392cf117e3139989f676aaaf086bd6204a8723 Mon Sep 17 00:00:00 2001
From: Kitti U
Date: Tue, 25 May 2021 12:30:31 +0700
Subject: [PATCH 16/49] Based on v14, use action_create_invoice instead
---
purchase_invoice_plan/models/purchase.py | 61 ++++---------------
.../wizard/purchase_make_planned_invoice.py | 2 +-
2 files changed, 12 insertions(+), 51 deletions(-)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 8ce8d2eeb13..87715f57c9e 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -96,59 +96,20 @@ def _next_date(self, installment_date, interval, interval_type):
next_date = fields.Date.to_string(next_date)
return next_date
- def action_invoice_create(self):
- journal = (
- self.env["account.move"]
- .with_context(
- default_move_type="in_invoice",
- default_currency_id=self.currency_id.id,
- default_company_id=self.env.user.company_id.id,
- )
- ._get_default_journal()
- )
- pre_inv = self.env["account.move"].new(
- {
- "move_type": "in_invoice",
- "purchase_id": self.id,
- "journal_id": journal.id,
- "currency_id": self.currency_id.id,
- "company_id": self.company_id.id,
- "invoice_origin": self.name,
- "ref": self.partner_ref or "",
- "narration": self.notes,
- "fiscal_position_id": self.fiscal_position_id.id,
- "invoice_payment_term_id": self.payment_term_id.id,
- }
- )
- pre_inv._onchange_purchase_auto_complete()
- inv_data = pre_inv._convert_to_write(pre_inv._cache)
- invoice = self.env["account.move"].create(inv_data)
- if not invoice.invoice_line_ids:
- raise UserError(
- _(
- "There is no invoiceable line. If a product has a"
- "Delivered quantities invoicing policy, please make sure"
- "that a quantity has been delivered."
- )
- )
- invoice._onchange_partner_id()
- invoice.message_post_with_view(
- "mail.message_origin_link",
- values={"self": invoice, "origin": self},
- subtype_id=self.env.ref("mail.mt_note").id,
- )
+ def action_view_invoice(self, invoices=False):
invoice_plan_id = self._context.get("invoice_plan_id")
if invoice_plan_id:
plan = self.env["purchase.invoice.plan"].browse(invoice_plan_id)
- plan._compute_new_invoice_quantity(invoice)
- invoice.write(
- {
- "date": plan.plan_date,
- "invoice_date": plan.plan_date,
- }
- )
- plan.invoice_ids += invoice
- return invoice
+ for invoice in invoices:
+ plan._compute_new_invoice_quantity(invoice)
+ invoice.write(
+ {
+ "date": plan.plan_date,
+ "invoice_date": plan.plan_date,
+ }
+ )
+ plan.invoice_ids += invoice
+ return super().action_view_invoice(invoices=invoices)
class PurchaseInvoicePlan(models.Model):
diff --git a/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
index 0883bce1323..51629da89d3 100644
--- a/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
+++ b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
@@ -17,5 +17,5 @@ def create_invoices_by_plan(self):
or purchase.invoice_plan_ids.filtered("to_invoice")
)
for plan in invoice_plans.sorted("installment"):
- purchase.with_context(invoice_plan_id=plan.id).action_invoice_create()
+ purchase.with_context(invoice_plan_id=plan.id).action_create_invoice()
return {"type": "ir.actions.act_window_close"}
From a0d8f0cd4bd7c75a24eb22f5fd038a703fe6c07a Mon Sep 17 00:00:00 2001
From: Kitti U
Date: Tue, 25 May 2021 15:56:50 +0700
Subject: [PATCH 17/49] Add amount field in invoice plan (as helper to percent)
---
purchase_invoice_plan/models/purchase.py | 20 +++++++++++++++++++
.../tests/test_purchase_invoice_plan.py | 8 ++++++++
purchase_invoice_plan/views/purchase_view.xml | 8 ++++++--
.../wizard/purchase_make_planned_invoice.py | 4 +++-
4 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 87715f57c9e..0365b0a8d7f 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -160,6 +160,13 @@ class PurchaseInvoicePlan(models.Model):
digits="Product Unit of Measure",
help="This percent will be used to calculate new quantity",
)
+ amount = fields.Float(
+ string="Amount",
+ digits="Product Price",
+ compute="_compute_amount",
+ inverse="_inverse_amount",
+ help="This amount will be used to calculate the percent",
+ )
invoice_ids = fields.Many2many(
comodel_name="account.move",
relation="purchase_invoice_plan_invoice_rel",
@@ -181,6 +188,19 @@ class PurchaseInvoicePlan(models.Model):
store=True,
)
+ @api.depends("percent")
+ def _compute_amount(self):
+ for rec in self:
+ rec.amount = rec.percent * rec.purchase_id.amount_untaxed / 100
+
+ @api.onchange("amount")
+ def _inverse_amount(self):
+ for rec in self:
+ if rec.purchase_id.amount_untaxed != 0:
+ rec.percent = rec.amount / rec.purchase_id.amount_untaxed * 100
+ else:
+ rec.percent = 0
+
@api.depends("purchase_id.state", "purchase_id.invoice_plan_ids.invoiced")
def _compute_to_invoice(self):
"""If any invoice is in draft/open/paid do not allow to create inv
diff --git a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
index 9a000898fe1..3f47759a005 100644
--- a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
+++ b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
@@ -71,6 +71,10 @@ def test_invoice_plan(self):
p.num_installment = 5
purchase_plan = p.save()
purchase_plan.with_context(ctx).purchase_create_invoice_plan()
+ # Change plan, so that the 1st installment is 1000 and 5th is 3000
+ self.assertEqual(len(self.test_po_product.invoice_plan_ids), 5)
+ self.test_po_product.invoice_plan_ids[0].amount = 1000
+ self.test_po_product.invoice_plan_ids[4].amount = 3000
self.test_po_product.button_confirm()
self.assertEqual(self.test_po_product.state, "purchase")
# Receive all products
@@ -79,6 +83,10 @@ def test_invoice_plan(self):
receive._action_done()
purchase_create = self.env["purchase.make.planned.invoice"].create({})
purchase_create.with_context(ctx).create_invoices_by_plan()
+ self.assertEqual(
+ self.test_po_product.amount_total,
+ sum(self.test_po_product.invoice_ids.mapped("amount_total")),
+ )
def test_unlink_invoice_plan(self):
ctx = {
diff --git a/purchase_invoice_plan/views/purchase_view.xml b/purchase_invoice_plan/views/purchase_view.xml
index eb56d24b680..0dc19c24f08 100644
--- a/purchase_invoice_plan/views/purchase_view.xml
+++ b/purchase_invoice_plan/views/purchase_view.xml
@@ -7,9 +7,11 @@
-
+
+
+
@@ -27,6 +29,7 @@
+
@@ -164,7 +167,8 @@
-
+
+
diff --git a/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
index 51629da89d3..566edefeb47 100644
--- a/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
+++ b/purchase_invoice_plan/wizard/purchase_make_planned_invoice.py
@@ -17,5 +17,7 @@ def create_invoices_by_plan(self):
or purchase.invoice_plan_ids.filtered("to_invoice")
)
for plan in invoice_plans.sorted("installment"):
- purchase.with_context(invoice_plan_id=plan.id).action_create_invoice()
+ purchase.sudo().with_context(
+ invoice_plan_id=plan.id
+ ).action_create_invoice()
return {"type": "ir.actions.act_window_close"}
From 1c368ddff1a520dc77eac63b5d4520ed0a792fd0 Mon Sep 17 00:00:00 2001
From: Kitti U
Date: Sat, 26 Jun 2021 18:51:26 +0700
Subject: [PATCH 18/49] Add sum invpoce plan percent and amount
---
purchase_invoice_plan/models/purchase.py | 34 +++++++++++++++++--
purchase_invoice_plan/views/purchase_view.xml | 15 +++++---
2 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 0365b0a8d7f..2c07deadf19 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -29,6 +29,20 @@ class PurchaseOrder(models.Model):
compute="_compute_ip_invoice_plan",
help="At least one invoice plan line pending to create invoice",
)
+ ip_total_percent = fields.Float(
+ compute="_compute_ip_total",
+ string="Percent",
+ )
+ ip_total_amount = fields.Monetary(
+ compute="_compute_ip_total",
+ string="Total Amount",
+ )
+
+ def _compute_ip_total(self):
+ for rec in self:
+ installments = rec.invoice_plan_ids.filtered("installment")
+ rec.ip_total_percent = sum(installments.mapped("percent"))
+ rec.ip_total_amount = sum(installments.mapped("amount"))
def _compute_ip_invoice_plan(self):
for rec in self:
@@ -191,15 +205,29 @@ class PurchaseInvoicePlan(models.Model):
@api.depends("percent")
def _compute_amount(self):
for rec in self:
+ if rec.last:
+ installments = rec.purchase_id.invoice_plan_ids.filtered(
+ lambda l: l.invoice_type == "installment"
+ )
+ prev_amount = sum((installments - rec).mapped("amount"))
+ rec.amount = rec.purchase_id.amount_untaxed - prev_amount
+ continue
rec.amount = rec.percent * rec.purchase_id.amount_untaxed / 100
- @api.onchange("amount")
+ @api.onchange("amount", "percent")
def _inverse_amount(self):
for rec in self:
if rec.purchase_id.amount_untaxed != 0:
+ if rec.last:
+ installments = rec.purchase_id.invoice_plan_ids.filtered(
+ lambda l: l.invoice_type == "installment"
+ )
+ prev_percent = sum((installments - rec).mapped("percent"))
+ rec.percent = 100 - prev_percent
+ continue
rec.percent = rec.amount / rec.purchase_id.amount_untaxed * 100
- else:
- rec.percent = 0
+ continue
+ rec.percent = 0
@api.depends("purchase_id.state", "purchase_id.invoice_plan_ids.invoiced")
def _compute_to_invoice(self):
diff --git a/purchase_invoice_plan/views/purchase_view.xml b/purchase_invoice_plan/views/purchase_view.xml
index 0dc19c24f08..7f1e17c0a1e 100644
--- a/purchase_invoice_plan/views/purchase_view.xml
+++ b/purchase_invoice_plan/views/purchase_view.xml
@@ -7,11 +7,11 @@
-
-
+
+
-
+
@@ -87,6 +87,10 @@
context="{'tree_view_ref': 'view_purchase_invoice_plan_tree'}"
attrs="{'invisible': [('invoice_plan_ids', '=', [])], 'readonly': [('invoice_count', '>', 0)]}"
/>
+
+
+
+
@@ -167,10 +171,11 @@
-
-
+
+
+
From 6951a677728710ed6971e65e96e298866eccebfd Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Sat, 7 Aug 2021 05:01:49 +0000
Subject: [PATCH 19/49] [UPD] Update purchase_invoice_plan.pot
---
.../i18n/purchase_invoice_plan.pot | 30 +++++++++++++++----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
index e088a11b0ef..ab2a42685fd 100644
--- a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
+++ b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
@@ -13,6 +13,12 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__amount
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_tree_readonly
+msgid "Amount"
+msgstr ""
+
#. module: purchase_invoice_plan
#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.purchase_order_form
msgid "Are you sure to remove this invoice plan?"
@@ -175,6 +181,11 @@ msgstr ""
msgid "Invoices"
msgstr ""
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__last
+msgid "Last Installment"
+msgstr ""
+
#. module: purchase_invoice_plan
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan____last_update
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan____last_update
@@ -197,6 +208,11 @@ msgstr ""
msgid "Last Updated on"
msgstr ""
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,help:purchase_invoice_plan.field_purchase_invoice_plan__last
+msgid "Last installment will create invoice use remaining amount"
+msgstr ""
+
#. module: purchase_invoice_plan
#: model:ir.model.fields.selection,name:purchase_invoice_plan.selection__purchase_create_invoice_plan__interval_type__month
msgid "Month"
@@ -220,6 +236,8 @@ msgstr ""
#. module: purchase_invoice_plan
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__percent
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__ip_total_percent
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_tree_readonly
msgid "Percent"
msgstr ""
@@ -302,11 +320,8 @@ msgid "Supplier"
msgstr ""
#. module: purchase_invoice_plan
-#: code:addons/purchase_invoice_plan/models/purchase.py:0
-#, python-format
-msgid ""
-"There is no invoiceable line. If a product has aDelivered quantities "
-"invoicing policy, please make surethat a quantity has been delivered."
+#: model:ir.model.fields,help:purchase_invoice_plan.field_purchase_invoice_plan__amount
+msgid "This amount will be used to calculate the percent"
msgstr ""
#. module: purchase_invoice_plan
@@ -329,6 +344,11 @@ msgstr ""
msgid "To Approve"
msgstr ""
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__ip_total_amount
+msgid "Total Amount"
+msgstr ""
+
#. module: purchase_invoice_plan
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__invoice_type
msgid "Type"
From 14574e4bfa99beb47026e033660afa37159d6921 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Sat, 7 Aug 2021 05:22:47 +0000
Subject: [PATCH 20/49] purchase_invoice_plan 14.0.1.1.0
---
purchase_invoice_plan/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index a78c5639da3..35e88c1b9a4 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "14.0.1.0.1",
+ "version": "14.0.1.1.0",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow",
From 2b61e8eebc3ab2e436e71f817c713cf407258901 Mon Sep 17 00:00:00 2001
From: newtratip
Date: Wed, 25 Aug 2021 22:09:04 +0700
Subject: [PATCH 21/49] [14.0][FIX] Change action_confirm to button_confirm
---
purchase_invoice_plan/models/purchase.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 2c07deadf19..0766b2df8ba 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -61,10 +61,10 @@ def _check_invoice_plan(self):
_("Please fill percentage for all invoice plan lines")
)
- def action_confirm(self):
+ def button_confirm(self):
if self.filtered(lambda r: r.use_invoice_plan and not r.invoice_plan_ids):
raise UserError(_("Use Invoice Plan selected, but no plan created"))
- return super().action_confirm()
+ return super().button_confirm()
def create_invoice_plan(
self, num_installment, installment_date, interval, interval_type
From 7566cb5f7ce08b752d4530797e9f1d0565c741f9 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 2 Sep 2021 08:12:01 +0000
Subject: [PATCH 22/49] purchase_invoice_plan 14.0.1.1.1
---
purchase_invoice_plan/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index 35e88c1b9a4..c92cff2baa4 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "14.0.1.1.0",
+ "version": "14.0.1.1.1",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow",
From c4e0170c248c6affe0572a2aecaadc70b4666167 Mon Sep 17 00:00:00 2001
From: oca-git-bot
Date: Thu, 31 Mar 2022 17:18:42 +0200
Subject: [PATCH 23/49] [IMP] update dotfiles [ci skip]
---
purchase_invoice_plan/models/purchase.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 0766b2df8ba..efffd607da7 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -267,7 +267,7 @@ def _compute_new_invoice_quantity(self, invoice_move):
move._move_autocomplete_invoice_lines_values() # recompute dr/cr
def _update_new_quantity(self, line, percent):
- """ Hook function """
+ """Hook function"""
plan_qty = self._get_plan_qty(line.purchase_line_id, percent)
prec = line.purchase_line_id.product_uom.rounding
if float_compare(abs(plan_qty), abs(line.quantity), prec) == 1:
From c34e08cbbe56cf4d1d9abbd27f11261f6e9bcb25 Mon Sep 17 00:00:00 2001
From: Kitti U
Date: Fri, 13 Aug 2021 16:41:29 +0700
Subject: [PATCH 24/49] [14.0][IMP] purchase_ivoice_plan, non-editable
installment
---
purchase_invoice_plan/__manifest__.py | 1 +
purchase_invoice_plan/data/purchase_data.xml | 6 +++
purchase_invoice_plan/models/purchase.py | 38 +++++++++++++++++--
purchase_invoice_plan/views/purchase_view.xml | 30 ++++++++++++---
4 files changed, 65 insertions(+), 10 deletions(-)
create mode 100644 purchase_invoice_plan/data/purchase_data.xml
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index c92cff2baa4..696c1385d42 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -12,6 +12,7 @@
"depends": ["purchase_open_qty", "purchase_stock"],
"data": [
"security/ir.model.access.csv",
+ "data/purchase_data.xml",
"wizard/purchase_create_invoice_plan_view.xml",
"wizard/purchase_make_planned_invoice_view.xml",
"views/purchase_view.xml",
diff --git a/purchase_invoice_plan/data/purchase_data.xml b/purchase_invoice_plan/data/purchase_data.xml
new file mode 100644
index 00000000000..a1f367d7278
--- /dev/null
+++ b/purchase_invoice_plan/data/purchase_data.xml
@@ -0,0 +1,6 @@
+
+
+ Purchase Invoice Plan Percent
+ 6
+
+
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index efffd607da7..0ea75826632 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -16,8 +16,6 @@ class PurchaseOrder(models.Model):
inverse_name="purchase_id",
string="Invoice Plan",
copy=False,
- readonly=True,
- states={"draft": [("readonly", False)]},
)
use_invoice_plan = fields.Boolean(
string="Use Invoice Plan",
@@ -52,6 +50,14 @@ def _compute_ip_invoice_plan(self):
and len(rec.invoice_plan_ids.filtered(lambda l: not l.invoiced))
)
+ @api.constrains("invoice_plan_ids")
+ def _check_ip_total_percent(self):
+ for rec in self:
+ installments = rec.invoice_plan_ids.filtered("installment")
+ ip_total_percent = sum(installments.mapped("percent"))
+ if float_round(ip_total_percent, 0) > 100:
+ raise UserError(_("Invoice plan total percentage must not exceed 100%"))
+
@api.constrains("state")
def _check_invoice_plan(self):
for rec in self:
@@ -73,7 +79,7 @@ def create_invoice_plan(
self.invoice_plan_ids.unlink()
invoice_plans = []
Decimal = self.env["decimal.precision"]
- prec = Decimal.precision_get("Product Unit of Measure")
+ prec = Decimal.precision_get("Purchase Invoice Plan Percent")
percent = float_round(1.0 / num_installment * 100, prec)
percent_last = 100 - (percent * (num_installment - 1))
for i in range(num_installment):
@@ -171,7 +177,7 @@ class PurchaseInvoicePlan(models.Model):
)
percent = fields.Float(
string="Percent",
- digits="Product Unit of Measure",
+ digits="Purchase Invoice Plan Percent",
help="This percent will be used to calculate new quantity",
)
amount = fields.Float(
@@ -201,6 +207,9 @@ class PurchaseInvoicePlan(models.Model):
help="If this line already invoiced",
store=True,
)
+ no_edit = fields.Boolean(
+ compute="_compute_no_edit",
+ )
@api.depends("percent")
def _compute_amount(self):
@@ -256,6 +265,14 @@ def _compute_last(self):
last = max(rec.purchase_id.invoice_plan_ids.mapped("installment"))
rec.last = rec.installment == last
+ def _no_edit(self):
+ self.ensure_one()
+ return self.invoiced
+
+ def _compute_no_edit(self):
+ for rec in self:
+ rec.no_edit = rec._no_edit()
+
def _compute_new_invoice_quantity(self, invoice_move):
self.ensure_one()
if self.last: # For last install, let the system do the calc.
@@ -284,3 +301,16 @@ def _update_new_quantity(self, line, percent):
def _get_plan_qty(self, order_line, percent):
plan_qty = order_line.product_qty * (percent / 100)
return plan_qty
+
+ def unlink(self):
+ lines = self.filtered("no_edit")
+ if lines:
+ installments = [str(x) for x in lines.mapped("installment")]
+ raise UserError(
+ _(
+ "Installment %s: already used and not allowed to delete.\n"
+ "Please discard changes."
+ )
+ % ", ".join(installments)
+ )
+ return super().unlink()
diff --git a/purchase_invoice_plan/views/purchase_view.xml b/purchase_invoice_plan/views/purchase_view.xml
index 7f1e17c0a1e..963841550d7 100644
--- a/purchase_invoice_plan/views/purchase_view.xml
+++ b/purchase_invoice_plan/views/purchase_view.xml
@@ -4,11 +4,29 @@
purchase.invoice.plan
-
-
-
-
-
+
+
+
+
+
+
@@ -85,7 +103,7 @@
From 2c16c511b9817c38a73da093e0e7c7e932040849 Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Sat, 30 Apr 2022 16:55:34 +0000
Subject: [PATCH 25/49] [UPD] Update purchase_invoice_plan.pot
---
.../i18n/purchase_invoice_plan.pot | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
index ab2a42685fd..7722eb26b6b 100644
--- a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
+++ b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
@@ -135,6 +135,14 @@ msgstr ""
msgid "Installment"
msgstr ""
+#. module: purchase_invoice_plan
+#: code:addons/purchase_invoice_plan/models/purchase.py:0
+#, python-format
+msgid ""
+"Installment %s: already used and not allowed to delete.\n"
+"Please discard changes."
+msgstr ""
+
#. module: purchase_invoice_plan
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__installment_date
msgid "Installment Date"
@@ -176,6 +184,12 @@ msgstr ""
msgid "Invoice Planning Detail"
msgstr ""
+#. module: purchase_invoice_plan
+#: code:addons/purchase_invoice_plan/models/purchase.py:0
+#, python-format
+msgid "Invoice plan total percentage must not exceed 100%"
+msgstr ""
+
#. module: purchase_invoice_plan
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__invoice_ids
msgid "Invoices"
@@ -223,6 +237,11 @@ msgstr ""
msgid "Next Invoice"
msgstr ""
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__no_edit
+msgid "No Edit"
+msgstr ""
+
#. module: purchase_invoice_plan
#: code:addons/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py:0
#, python-format
From 9986626f95149f2e7078fe1438c64ddb4178276b Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Sat, 30 Apr 2022 18:03:11 +0000
Subject: [PATCH 26/49] purchase_invoice_plan 14.0.1.2.0
---
purchase_invoice_plan/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index 696c1385d42..e88c1b47953 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "14.0.1.1.1",
+ "version": "14.0.1.2.0",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow",
From e0260b1ca0abafe4bef73a02749c892bef82ce34 Mon Sep 17 00:00:00 2001
From: Kitti U
Date: Tue, 17 May 2022 17:03:41 +0700
Subject: [PATCH 27/49] [14.0][FIX] purchase_invoice_plan, clean recompute tax
dr/cr
---
purchase_invoice_plan/models/purchase.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 0ea75826632..ead39292152 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -281,6 +281,7 @@ def _compute_new_invoice_quantity(self, invoice_move):
move = invoice_move.with_context({"check_move_validity": False})
for line in move.invoice_line_ids:
self._update_new_quantity(line, percent)
+ move.line_ids.filtered("exclude_from_invoice_tab").unlink()
move._move_autocomplete_invoice_lines_values() # recompute dr/cr
def _update_new_quantity(self, line, percent):
From e2df628356b130516df1f35ed0aa20d66055532a Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Tue, 17 May 2022 12:03:19 +0000
Subject: [PATCH 28/49] purchase_invoice_plan 14.0.1.2.1
---
purchase_invoice_plan/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index e88c1b47953..350aa076cd0 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "14.0.1.2.0",
+ "version": "14.0.1.2.1",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow",
From 7f04a0d1b31a4b8b0f56d0f786528c53f81e66aa Mon Sep 17 00:00:00 2001
From: Kitti U
Date: Thu, 12 May 2022 15:16:38 +0700
Subject: [PATCH 29/49] [14.0][ENH] purchase_invoice_plan, freeze plan amount
if already invoiced
---
purchase_invoice_plan/models/purchase.py | 13 +++++
.../tests/test_purchase_invoice_plan.py | 55 +++++++++++++++++++
purchase_invoice_plan/views/purchase_view.xml | 2 +
3 files changed, 70 insertions(+)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index ead39292152..ce7303aeb69 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -36,6 +36,7 @@ class PurchaseOrder(models.Model):
string="Total Amount",
)
+ @api.depends("invoice_plan_ids")
def _compute_ip_total(self):
for rec in self:
installments = rec.invoice_plan_ids.filtered("installment")
@@ -195,6 +196,11 @@ class PurchaseInvoicePlan(models.Model):
string="Invoices",
readonly=True,
)
+ amount_invoiced = fields.Float(
+ compute="_compute_invoiced",
+ store=True,
+ readonly=False,
+ )
to_invoice = fields.Boolean(
string="Next Invoice",
compute="_compute_to_invoice",
@@ -214,6 +220,12 @@ class PurchaseInvoicePlan(models.Model):
@api.depends("percent")
def _compute_amount(self):
for rec in self:
+ # With invoice already created, no recompute
+ if rec.invoiced:
+ rec.amount = rec.amount_invoiced
+ rec.percent = rec.amount / rec.purchase_id.amount_untaxed * 100
+ continue
+ # For last line, amount is the left over
if rec.last:
installments = rec.purchase_id.invoice_plan_ids.filtered(
lambda l: l.invoice_type == "installment"
@@ -259,6 +271,7 @@ def _compute_invoiced(self):
lambda l: l.state in ("draft", "posted")
)
rec.invoiced = invoiced and True or False
+ rec.amount_invoiced = invoiced[:1].amount_untaxed
def _compute_last(self):
for rec in self:
diff --git a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
index 3f47759a005..d396b5c4200 100644
--- a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
+++ b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
@@ -134,3 +134,58 @@ def test_error(self):
"\nProduct should be delivered before invoice"
)
self.assertEqual(e.exception.args[0], error_message)
+
+ def test_invoice_plan_po_edit(self):
+ """Case when some installment already invoiced,
+ but then, the PO line added. Test to ensure that
+ the invoiced amount of the done installment is fixed"""
+ ctx = {
+ "active_id": self.test_po_product.id,
+ "active_ids": [self.test_po_product.id],
+ "all_remain_invoices": False,
+ }
+ # Create purchase plan
+ with Form(self.PurchaseInvoicePlan) as p:
+ p.num_installment = 5
+ purchase_plan = p.save()
+ purchase_plan.with_context(ctx).purchase_create_invoice_plan()
+ # Change plan, so that the 1st installment is 1000 and 5th is 3000
+ self.assertEqual(len(self.test_po_product.invoice_plan_ids), 5)
+ first_install = self.test_po_product.invoice_plan_ids[0]
+ first_install.amount = 1000
+ self.test_po_product.invoice_plan_ids[4].amount = 3000
+ self.test_po_product.button_confirm()
+ self.assertEqual(self.test_po_product.state, "purchase")
+ # Receive all products
+ receive = self.test_po_product.picking_ids.filtered(lambda l: l.state != "done")
+ receive.move_ids_without_package.quantity_done = 10.0
+ receive._action_done()
+ purchase_create = self.env["purchase.make.planned.invoice"].create({})
+ # Create only the 1st invoice, amount should be 1000, and percent is 10
+ purchase_create.with_context(ctx).create_invoices_by_plan()
+ self.assertEqual(first_install.amount, 1000)
+ self.assertEqual(first_install.percent, 10)
+ # Add new PO line with amount = 1000, check that only percent is changed
+ self.test_po_product.write(
+ {
+ "order_line": [
+ (
+ 0,
+ 0,
+ {
+ "name": "PO-Product-NEW",
+ "product_id": self.test_product.id,
+ "date_planned": fields.Datetime.now(),
+ "product_qty": 1,
+ "product_uom": self.test_product.uom_id.id,
+ "price_unit": 1000,
+ },
+ )
+ ],
+ }
+ )
+ # Overall amount changed to 11000, install amount not changed, only percent changed.
+ self.assertEqual(self.test_po_product.amount_total, 11000)
+ self.test_po_product.invoice_plan_ids._compute_amount()
+ self.assertEqual(first_install.amount, 1000)
+ self.assertEqual(first_install.percent, 9.090909)
diff --git a/purchase_invoice_plan/views/purchase_view.xml b/purchase_invoice_plan/views/purchase_view.xml
index 963841550d7..a1e0c0b7790 100644
--- a/purchase_invoice_plan/views/purchase_view.xml
+++ b/purchase_invoice_plan/views/purchase_view.xml
@@ -27,6 +27,7 @@
optional="show"
attrs="{'readonly': [('no_edit', '=', True)]}"
/>
+
@@ -191,6 +192,7 @@
+
From 6d92f4df164a97be6c5d66b2c1112b9c0ecf2931 Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Thu, 26 May 2022 06:24:36 +0000
Subject: [PATCH 30/49] [UPD] Update purchase_invoice_plan.pot
---
purchase_invoice_plan/i18n/purchase_invoice_plan.pot | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
index 7722eb26b6b..c4fabf5a83a 100644
--- a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
+++ b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
@@ -15,10 +15,16 @@ msgstr ""
#. module: purchase_invoice_plan
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__amount
+#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_tree
#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.view_purchase_invoice_plan_tree_readonly
msgid "Amount"
msgstr ""
+#. module: purchase_invoice_plan
+#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__amount_invoiced
+msgid "Amount Invoiced"
+msgstr ""
+
#. module: purchase_invoice_plan
#: model_terms:ir.ui.view,arch_db:purchase_invoice_plan.purchase_order_form
msgid "Are you sure to remove this invoice plan?"
From bf1af80564d67b162ec21cad4fc098f06d01e3ad Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 26 May 2022 07:35:18 +0000
Subject: [PATCH 31/49] purchase_invoice_plan 14.0.1.3.0
---
purchase_invoice_plan/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index 350aa076cd0..b8a35527632 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "14.0.1.2.1",
+ "version": "14.0.1.3.0",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow",
From e9922ffbc119e841cc14f83f99628a2fb1835c13 Mon Sep 17 00:00:00 2001
From: ps-tubtim
Date: Thu, 16 Jun 2022 15:28:53 +0700
Subject: [PATCH 32/49] [FIX] purchase_invoice_plan: error when invoice=False
---
purchase_invoice_plan/models/purchase.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index ce7303aeb69..cfa605270c3 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -119,7 +119,7 @@ def _next_date(self, installment_date, interval, interval_type):
def action_view_invoice(self, invoices=False):
invoice_plan_id = self._context.get("invoice_plan_id")
- if invoice_plan_id:
+ if invoice_plan_id and invoices:
plan = self.env["purchase.invoice.plan"].browse(invoice_plan_id)
for invoice in invoices:
plan._compute_new_invoice_quantity(invoice)
From 4d855584cffba925563b4d3d2b8c2d13460d8834 Mon Sep 17 00:00:00 2001
From: ps-tubtim
Date: Fri, 17 Jun 2022 10:50:22 +0700
Subject: [PATCH 33/49] [FIX] purchase_invoice_plan: add _get_amount_invoice
---
purchase_invoice_plan/models/purchase.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index cfa605270c3..56410e7d89c 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -264,6 +264,10 @@ def _compute_to_invoice(self):
rec.to_invoice = True
break
+ def _get_amount_invoice(self, invoices):
+ """Hook function"""
+ return sum(invoices.mapped("amount_untaxed"))
+
@api.depends("invoice_ids.state")
def _compute_invoiced(self):
for rec in self:
@@ -271,7 +275,7 @@ def _compute_invoiced(self):
lambda l: l.state in ("draft", "posted")
)
rec.invoiced = invoiced and True or False
- rec.amount_invoiced = invoiced[:1].amount_untaxed
+ rec.amount_invoiced = rec._get_amount_invoice(invoiced[:1])
def _compute_last(self):
for rec in self:
From faf6a804fad9469bc4ffe7cfb17f75d8900ccaeb Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Tue, 21 Jun 2022 11:32:07 +0000
Subject: [PATCH 34/49] purchase_invoice_plan 14.0.1.3.1
---
purchase_invoice_plan/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index b8a35527632..d798d1956e0 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "14.0.1.3.0",
+ "version": "14.0.1.3.1",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow",
From f9611a8c3b24b3bede374b2ab403692f86a25841 Mon Sep 17 00:00:00 2001
From: Saran440
Date: Mon, 30 Jan 2023 15:00:58 +0700
Subject: [PATCH 35/49] [MIG] purchase_invoice_plan: Migration to 15.0
---
purchase_invoice_plan/__manifest__.py | 2 +-
purchase_invoice_plan/models/purchase.py | 14 ++---
.../tests/test_purchase_invoice_plan.py | 52 +++++++++++++++----
.../wizard/purchase_create_invoice_plan.py | 3 --
4 files changed, 48 insertions(+), 23 deletions(-)
diff --git a/purchase_invoice_plan/__manifest__.py b/purchase_invoice_plan/__manifest__.py
index d798d1956e0..9bfb7eee7bc 100644
--- a/purchase_invoice_plan/__manifest__.py
+++ b/purchase_invoice_plan/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Purchase Invoice Plan",
"summary": "Add to purchases order, ability to manage future invoice plan",
- "version": "14.0.1.3.1",
+ "version": "15.0.1.0.0",
"author": "Ecosoft,Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/purchase-workflow",
diff --git a/purchase_invoice_plan/models/purchase.py b/purchase_invoice_plan/models/purchase.py
index 56410e7d89c..82490cdc8a1 100644
--- a/purchase_invoice_plan/models/purchase.py
+++ b/purchase_invoice_plan/models/purchase.py
@@ -18,7 +18,6 @@ class PurchaseOrder(models.Model):
copy=False,
)
use_invoice_plan = fields.Boolean(
- string="Use Invoice Plan",
default=False,
copy=False,
)
@@ -158,11 +157,8 @@ class PurchaseInvoicePlan(models.Model):
store=True,
index=True,
)
- installment = fields.Integer(
- string="Installment",
- )
+ installment = fields.Integer()
plan_date = fields.Date(
- string="Plan Date",
required=True,
)
invoice_type = fields.Selection(
@@ -177,12 +173,10 @@ class PurchaseInvoicePlan(models.Model):
help="Last installment will create invoice use remaining amount",
)
percent = fields.Float(
- string="Percent",
digits="Purchase Invoice Plan Percent",
help="This percent will be used to calculate new quantity",
)
amount = fields.Float(
- string="Amount",
digits="Product Price",
compute="_compute_amount",
inverse="_inverse_amount",
@@ -295,7 +289,7 @@ def _compute_new_invoice_quantity(self, invoice_move):
if self.last: # For last install, let the system do the calc.
return
percent = self.percent
- move = invoice_move.with_context({"check_move_validity": False})
+ move = invoice_move.with_context(**{"check_move_validity": False})
for line in move.invoice_line_ids:
self._update_new_quantity(line, percent)
move.line_ids.filtered("exclude_from_invoice_tab").unlink()
@@ -308,10 +302,10 @@ def _update_new_quantity(self, line, percent):
if float_compare(abs(plan_qty), abs(line.quantity), prec) == 1:
raise ValidationError(
_(
- "Plan quantity: %s, exceed invoiceable quantity: %s"
+ "Plan quantity: %(plan)s, exceed invoiceable quantity: %(qty)s"
"\nProduct should be delivered before invoice"
)
- % (plan_qty, line.quantity)
+ % {"plan": plan_qty, "qty": line.quantity}
)
line.write({"quantity": plan_qty})
diff --git a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
index d396b5c4200..eb38a6e0744 100644
--- a/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
+++ b/purchase_invoice_plan/tests/test_purchase_invoice_plan.py
@@ -1,8 +1,10 @@
# Copyright 2019 Ecosoft (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
+from freezegun import freeze_time
+
from odoo import fields
-from odoo.exceptions import ValidationError
+from odoo.exceptions import UserError, ValidationError
from odoo.tests.common import Form, TransactionCase
@@ -70,7 +72,7 @@ def test_invoice_plan(self):
with Form(self.PurchaseInvoicePlan) as p:
p.num_installment = 5
purchase_plan = p.save()
- purchase_plan.with_context(ctx).purchase_create_invoice_plan()
+ purchase_plan.with_context(**ctx).purchase_create_invoice_plan()
# Change plan, so that the 1st installment is 1000 and 5th is 3000
self.assertEqual(len(self.test_po_product.invoice_plan_ids), 5)
self.test_po_product.invoice_plan_ids[0].amount = 1000
@@ -82,7 +84,7 @@ def test_invoice_plan(self):
receive.move_ids_without_package.quantity_done = 10.0
receive._action_done()
purchase_create = self.env["purchase.make.planned.invoice"].create({})
- purchase_create.with_context(ctx).create_invoices_by_plan()
+ purchase_create.with_context(**ctx).create_invoices_by_plan()
self.assertEqual(
self.test_po_product.amount_total,
sum(self.test_po_product.invoice_ids.mapped("amount_total")),
@@ -96,7 +98,7 @@ def test_unlink_invoice_plan(self):
with Form(self.PurchaseInvoicePlan) as p:
p.num_installment = 5
plan = p.save()
- plan.with_context(ctx).purchase_create_invoice_plan()
+ plan.with_context(**ctx).purchase_create_invoice_plan()
# Remove it
self.test_po_product.remove_invoice_plan()
self.assertFalse(self.test_po_product.invoice_plan_ids)
@@ -107,20 +109,32 @@ def test_error(self):
"active_ids": [self.test_po_product.id],
"all_remain_invoices": True,
}
+ # UserError Use Invoice Plan selected, but no plan created
+ with self.assertRaises(UserError):
+ self.test_po_product.button_confirm()
# ValidationError Number of Installment <= 1
with self.assertRaises(ValidationError) as e:
with Form(self.PurchaseInvoicePlan) as p:
p.num_installment = 0
- p.save()
+ p.save()
error_message = "Number Installment must greater than 1"
self.assertEqual(e.exception.args[0], error_message)
# Create purchase plan
with Form(self.PurchaseInvoicePlan) as p:
p.num_installment = 5
purchase_plan = p.save()
- purchase_plan.with_context(ctx).purchase_create_invoice_plan()
+ purchase_plan.with_context(**ctx).purchase_create_invoice_plan()
+ # Test exceed percent
+ with self.assertRaises(UserError):
+ self.test_po_product.invoice_plan_ids[0].percent = 99
+ self.test_po_product._check_ip_total_percent()
self.test_po_product.button_confirm()
self.assertEqual(self.test_po_product.state, "purchase")
+ # UserError Please fill percentage for all invoice plan lines
+ with self.assertRaises(UserError):
+ for per in self.test_po_product.invoice_plan_ids:
+ per.percent = 0
+ self.test_po_product._check_invoice_plan()
# Receive product 1 unit
receive = self.test_po_product.picking_ids.filtered(lambda l: l.state != "done")
receive.move_ids_without_package.quantity_done = 1.0
@@ -128,7 +142,7 @@ def test_error(self):
# ValidationError Create all invoice plan - Receive < Invoice require
purchase_create = self.env["purchase.make.planned.invoice"].create({})
with self.assertRaises(ValidationError) as e:
- purchase_create.with_context(ctx).create_invoices_by_plan()
+ purchase_create.with_context(**ctx).create_invoices_by_plan()
error_message = (
"Plan quantity: 2.0, exceed invoiceable quantity: 1.0"
"\nProduct should be delivered before invoice"
@@ -148,7 +162,7 @@ def test_invoice_plan_po_edit(self):
with Form(self.PurchaseInvoicePlan) as p:
p.num_installment = 5
purchase_plan = p.save()
- purchase_plan.with_context(ctx).purchase_create_invoice_plan()
+ purchase_plan.with_context(**ctx).purchase_create_invoice_plan()
# Change plan, so that the 1st installment is 1000 and 5th is 3000
self.assertEqual(len(self.test_po_product.invoice_plan_ids), 5)
first_install = self.test_po_product.invoice_plan_ids[0]
@@ -162,7 +176,7 @@ def test_invoice_plan_po_edit(self):
receive._action_done()
purchase_create = self.env["purchase.make.planned.invoice"].create({})
# Create only the 1st invoice, amount should be 1000, and percent is 10
- purchase_create.with_context(ctx).create_invoices_by_plan()
+ purchase_create.with_context(**ctx).create_invoices_by_plan()
self.assertEqual(first_install.amount, 1000)
self.assertEqual(first_install.percent, 10)
# Add new PO line with amount = 1000, check that only percent is changed
@@ -189,3 +203,23 @@ def test_invoice_plan_po_edit(self):
self.test_po_product.invoice_plan_ids._compute_amount()
self.assertEqual(first_install.amount, 1000)
self.assertEqual(first_install.percent, 9.090909)
+ with self.assertRaises(UserError):
+ self.test_po_product.remove_invoice_plan()
+
+ @freeze_time("2022-01-01")
+ def test_next_date(self):
+ ctx = {
+ "active_id": self.test_po_product.id,
+ "active_ids": [self.test_po_product.id],
+ "all_remain_invoices": False,
+ }
+ # Create purchase plan
+ for item in ["day", "month", "year"]:
+ with Form(self.PurchaseInvoicePlan) as p:
+ p.num_installment = 5
+ p.interval = 5
+ p.interval_type = item
+ purchase_plan = p.save()
+ purchase_plan.with_context(**ctx).purchase_create_invoice_plan()
+ self.assertEqual(len(self.test_po_product.invoice_plan_ids), 5)
+ self.test_po_product.remove_invoice_plan()
diff --git a/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py b/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
index 11dc6098c90..16616be7591 100644
--- a/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
+++ b/purchase_invoice_plan/wizard/purchase_create_invoice_plan.py
@@ -15,18 +15,15 @@ class PurchaseCreateInvoicePlan(models.TransientModel):
required=True,
)
installment_date = fields.Date(
- string="Installment Date",
default=fields.Date.context_today,
required=True,
)
interval = fields.Integer(
- string="Interval",
default=1,
required=True,
)
interval_type = fields.Selection(
[("day", "Day"), ("month", "Month"), ("year", "Year")],
- string="Interval Type",
default="month",
required=True,
)
From ffb42defc14a188bb09bfc85ee101b4eab9e4e69 Mon Sep 17 00:00:00 2001
From: oca-ci
Date: Wed, 8 Feb 2023 08:26:05 +0000
Subject: [PATCH 36/49] [UPD] Update purchase_invoice_plan.pot
---
purchase_invoice_plan/i18n/purchase_invoice_plan.pot | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
index c4fabf5a83a..94dccaf6717 100644
--- a/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
+++ b/purchase_invoice_plan/i18n/purchase_invoice_plan.pot
@@ -4,7 +4,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 14.0\n"
+"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -102,7 +102,6 @@ msgstr ""
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__display_name
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__display_name
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__display_name
-#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__display_name
msgid "Display Name"
msgstr ""
@@ -120,7 +119,6 @@ msgstr ""
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan__id
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan__id
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice__id
-#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order__id
msgid "ID"
msgstr ""
@@ -210,7 +208,6 @@ msgstr ""
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_create_invoice_plan____last_update
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_invoice_plan____last_update
#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_make_planned_invoice____last_update
-#: model:ir.model.fields,field_description:purchase_invoice_plan.field_purchase_order____last_update
msgid "Last Modified on"
msgstr ""
@@ -275,7 +272,7 @@ msgstr ""
#: code:addons/purchase_invoice_plan/models/purchase.py:0
#, python-format
msgid ""
-"Plan quantity: %s, exceed invoiceable quantity: %s\n"
+"Plan quantity: %(plan)s, exceed invoiceable quantity: %(qty)s\n"
"Product should be delivered before invoice"
msgstr ""
From 91121e02f1655e0211bc344fea9e33ef32bb7bb5 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Wed, 8 Feb 2023 08:32:13 +0000
Subject: [PATCH 37/49] [UPD] README.rst
---
purchase_invoice_plan/README.rst | 10 +++++-----
purchase_invoice_plan/static/description/index.html | 6 +++---
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/purchase_invoice_plan/README.rst b/purchase_invoice_plan/README.rst
index 1ef8f5cac6c..9c5610529db 100644
--- a/purchase_invoice_plan/README.rst
+++ b/purchase_invoice_plan/README.rst
@@ -14,13 +14,13 @@ Purchase Invoice Plan
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github
- :target: https://github.com/OCA/purchase-workflow/tree/14.0/purchase_invoice_plan
+ :target: https://github.com/OCA/purchase-workflow/tree/15.0/purchase_invoice_plan
:alt: OCA/purchase-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/purchase-workflow-14-0/purchase-workflow-14-0-purchase_invoice_plan
+ :target: https://translation.odoo-community.org/projects/purchase-workflow-15-0/purchase-workflow-15-0-purchase_invoice_plan
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/142/14.0
+ :target: https://runbot.odoo-community.org/runbot/142/15.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -57,7 +57,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -96,6 +96,6 @@ Current `maintainer `__:
|maintainer-kittiu|
-This module is part of the `OCA/purchase-workflow `_ project on GitHub.
+This module is part of the `OCA/purchase-workflow `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/purchase_invoice_plan/static/description/index.html b/purchase_invoice_plan/static/description/index.html
index 2e35c38c448..8fb62fc98c5 100644
--- a/purchase_invoice_plan/static/description/index.html
+++ b/purchase_invoice_plan/static/description/index.html
@@ -367,7 +367,7 @@
Purchase Invoice Plan
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
By standard feature, user can gradually create partial invoices, one by one and
in step create invoice the standard call invoice.
This module add ability to create invoices based on the predefined invoice plan,
@@ -408,7 +408,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-feedback.