Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[18.0][MIG] rma_purchase #560

Open
wants to merge 69 commits into
base: 18.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
8e1afc9
init branch
JordiBForgeFlow Jul 27, 2017
ff9057b
[9.0][FIX] rma:
LoisRForgeFlow Aug 2, 2017
c6e1f68
[IMP] default operation in product and product_categ for customer and…
AaronHForgeFlow Aug 16, 2017
9f61036
[9.0][IMP] rma_purchase:
LoisRForgeFlow Aug 25, 2017
4a63f01
[9.0][REW] rma_purchase: adapt
LoisRForgeFlow Oct 18, 2017
11e82e2
[9.0][IMP] rma: add constrains
LoisRForgeFlow Oct 19, 2017
645a32c
[9.0][FIX] wizards need to specify partner.
LoisRForgeFlow Oct 19, 2017
6b382a6
[9.0][IMP] rma_purchase: allow to search by order reference
LoisRForgeFlow Nov 8, 2017
9c3c92d
[FIX] allow child partners too
LoisRForgeFlow Nov 13, 2017
6a211dd
[9.0][IMP] rma: add link to source SO and PO
LoisRForgeFlow Nov 13, 2017
4cf66b6
[MIG]rma_purchase v10
AaronHForgeFlow Dec 20, 2017
5f1f151
[IMP] Improved Unit Test Case and Fixed Travis
nikul-serpentcs Nov 10, 2017
faa061c
[FIX]various fixes
AaronHForgeFlow Jan 2, 2018
9a8b648
[MIG] Migrated UT & Fixed Travis
nikul-serpentcs Jan 5, 2018
29b5b5a
[MIG] Migrate configuration and cleanup
max3903 Feb 9, 2018
ba03171
[11.0] MIG: rma_purchase
Feb 9, 2018
dd82feb
[FIX] Add read access to purchase order and po line
max3903 Jun 26, 2018
8ebf688
[FIX] TypeError: unhashable type: 'list'
Jul 19, 2018
c610bfd
Revert "[FIX] TypeError: unhashable type: 'list'"
Jul 19, 2018
658851c
[IMP]name get when filling form purchase order lines
AaronHForgeFlow May 25, 2018
da71201
[9.0] rma_purchase: add purchase_policy
LoisRForgeFlow May 25, 2018
2353745
[IMP] code
Jul 20, 2018
ccaf879
[IMP] rma_operation
Jul 20, 2018
0184818
Revert "[IMP] code"
Jul 22, 2018
e07f156
Revert "[IMP] rma_operation"
Jul 22, 2018
94d4f1a
[MIG] Purchase policy
Jul 22, 2018
b3908d3
[RM] ValidationError message if there is no purchase order found
Jul 26, 2018
36a9076
[FIX] flake8
Jul 26, 2018
0c51a1e
[FIX] issue of name_get purchase order line id
Jul 27, 2018
4f05e89
[IMP]create PO from wizard
AaronHForgeFlow Jul 27, 2018
46b3e74
[IMP]include action to see PO generated from the RMA
AaronHForgeFlow Jul 27, 2018
9404f88
[ENH] change from customer to supplier domain and lable in Purchase w…
Jul 27, 2018
dda4c15
[ENH] make supplier readonly in Create Purchase Order wizard
Jul 27, 2018
4f7939b
[9.0][REW] rma_purchase: complete rework of tests
LoisRForgeFlow May 17, 2018
1f823ca
[FIX]currency_id was not filled
AaronHForgeFlow Oct 4, 2018
3a92f06
[WIP][MIG][12.0] rma_purchase
murtuzasaleh Mar 20, 2019
7675324
[SET] Correct website URL for RMA modules
May 24, 2019
37016a4
[FIX]remove autoinstall for rma_account, rma_sale and rma_purchase mo…
AaronHForgeFlow Oct 29, 2019
df71f98
[FIX] action returned when creating purchase orders from rma
AaronHForgeFlow Nov 29, 2019
7a33e59
[FIX] default_gets: avoid using shadowname 'fields'
MiquelRForgeFlow Nov 29, 2019
69e532d
[IMP] rma_purchase: black, isort, prettier
MateuGForgeFlow Dec 22, 2020
2793b11
[MIG] rma_purchase: Migration to 14.0
MateuGForgeFlow Dec 23, 2020
54b1259
[IMP] rma_purchase: adapt to simplification on rma.line form view.
LoisRForgeFlow Mar 26, 2021
ce9608a
[14.0][MIG] rma*: ir.actions.act_window has different access
LoisRForgeFlow Apr 16, 2021
98eae6a
Fix Pre-commit Websites
MateuGForgeFlow Oct 6, 2021
1413845
[MIG] rma_purchase: Migration to 15.0
JasminSForgeFlow Jan 7, 2022
23353f3
[IMP] COPIER UPDATE: black, isort, prettier
AaronHForgeFlow Apr 22, 2022
e769004
[IMP] rma: Refactor all rma modules in order to consider using the co…
JordiBForgeFlow Mar 2, 2022
5508ca1
[15.0][IMP] Tests for stock valuation
AaronHForgeFlow Mar 4, 2022
4b1e029
[15.0][FIX] rma_purchase: fixup of procurement
DavidJForgeFlow Jul 11, 2022
4289ce1
[FIX] rma_purchase: fix author in manifest
LoisRForgeFlow Nov 7, 2022
b166f76
[IMP] fp-303: add changes from 14.0
Nov 8, 2022
444da13
[FIX] include anglo-saxon price unit calculation in refunds.
JordiBForgeFlow Nov 21, 2022
ad71381
[IMP] centralize the logic to get the correct cost of the RMA.
JordiBForgeFlow Nov 23, 2022
0029329
[IMP] calculate refund unit price
JordiBForgeFlow Nov 29, 2022
4924254
[FIX] rma_purchase: Reconcile the interim accounts when vendor bill i…
JordiBForgeFlow Nov 29, 2022
29d1969
[FIX] rma_purchase: `purchase_line_id` filled with wrong model.
LoisRForgeFlow Dec 27, 2022
2e321e0
[FIX] rma_purchase: Ensure that configuration on the operation is app…
LoisRForgeFlow Dec 28, 2022
8f2fffe
[IMP] rma_purchase: copy group description to rma lines
LoisRForgeFlow Jan 2, 2023
550c245
[IMP] rma_purchase: button cancel
DavidJForgeFlow Feb 15, 2023
51f302d
[MIG] rma_purchase: Migration to 16.0
DavidJForgeFlow Feb 23, 2023
bfc8233
[IMP] rma_purchase: black, isort, prettier
AaronHForgeFlow May 6, 2024
ef3c219
[MIG] rma_purchase: Migration to v17
CarlosVForgeFlow May 6, 2024
48260da
[FIX] rma_purchase: name_search migration
AaronHForgeFlow May 7, 2024
d77729f
[FIX] rma_purchase: tests not fetching refund_line_ids correctly
AaronHForgeFlow May 8, 2024
76dd218
[IMP] rma_purchase: add test return_and_refund_diff_price
mariadforgeflow Feb 27, 2023
747c294
[FIX] rma_purchase: write-off differences in price between rma line a…
mariadforgeflow Feb 27, 2023
cb13734
[FIX] rma_purchase: add dependency with purchase_stock
JordiBForgeFlow May 22, 2024
4b65987
[MIG] rma_purchase: Migration to 18.0
JasminSForgeFlow Nov 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions rma_purchase/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg
:alt: License LGPL-3

============
RMA Purchase
============

This modules extend the RMA functionality allowing to use Purchase Orders as
a RMA source.

Usage
=====

To add lines to a RMA from PO act as follows:

#. Go to a supplier RMA.
#. Fill the *Supplier* field.
#. Click on *Add From Purchase Order*.
#. Select the Purchase Order.
#. Click on *Add an item* and select the lines you would like to add to the
RMA.
#. Hit *Confirm*.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues
<https://github.com/Eficent/stock-rma/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.

Credits
=======

Contributors
------------

* Jordi Ballester Alomar <jordi.ballester@eficent.com>
* Aaron Henriquez <ahenriquez@eficent.com>
* Lois Rilo <lois.rilo@eficent.com>
* Bhavesh Odedra <bodedra@opensourceintegrators.com>
* Serpent Consulting Services Pvt. Ltd. <support@serpentcs.com>

Maintainer
----------

This module is maintained by Eficent.
2 changes: 2 additions & 0 deletions rma_purchase/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizards
22 changes: 22 additions & 0 deletions rma_purchase/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2017-2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
{
"name": "RMA Purchase",
"version": "18.0.1.0.0",
"category": "RMA",
"summary": "RMA from PO",
"license": "LGPL-3",
"author": "ForgeFlow, Odoo Community Association (OCA)",
"website": "https://github.com/ForgeFlow",
"depends": ["rma_account", "purchase_stock"],
"data": [
"wizards/rma_order_line_make_purchase_order_view.xml",
"security/ir.model.access.csv",
"views/rma_operation_view.xml",
"views/rma_order_view.xml",
"views/rma_order_line_view.xml",
"wizards/rma_add_purchase.xml",
],
"installable": True,
"auto_install": True,
}
8 changes: 8 additions & 0 deletions rma_purchase/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from . import rma_order
from . import rma_order_line
from . import purchase_order
from . import purchase_order_line
from . import rma_operation
from . import procurement
from . import account_move
from . import account_move_line
213 changes: 213 additions & 0 deletions rma_purchase/models/account_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
# Copyright 2017-22 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)

from odoo import fields, models
from odoo.tools.float_utils import float_compare


class AccountMove(models.Model):
_inherit = "account.move"

def _prepare_invoice_line_from_rma_line(self, line):
data = super()._prepare_invoice_line_from_rma_line(line)
if line.purchase_order_line_id:
data["purchase_line_id"] = line.purchase_order_line_id.id
return data

def action_post(self):
res = super().action_post()
for move in self:
rma_mls = move.line_ids.filtered(lambda x: x.rma_line_id)
if rma_mls:
# Try to reconcile the interim accounts for RMA lines
rmas = rma_mls.mapped("rma_line_id")
for rma in rmas:
product_accounts = (
rma.product_id.product_tmpl_id._get_product_accounts()
)
if rma.type == "customer":
product_interim_account = product_accounts["stock_output"]
else:
product_interim_account = product_accounts["stock_input"]
if product_interim_account.reconcile:
# Get the in and out moves
amls = self.env["account.move.line"].search(
[
("rma_line_id", "=", rma.id),
("account_id", "=", product_interim_account.id),
("parent_state", "=", "posted"),
("reconciled", "=", False),
]
)
amls.reconcile()
return res

def _stock_account_prepare_anglo_saxon_in_lines_vals(self):
lines_vals_list_rma = []
rma_refunds = self.env["account.move"]
price_unit_prec = self.env["decimal.precision"].precision_get("Product Price")
for move in self:
if (
move.move_type != "in_refund"
or not move.company_id.anglo_saxon_accounting
):
continue
move = move.with_company(move.company_id)
for line in move.invoice_line_ids.filtered(lambda il: il.rma_line_id):
# Filter out lines being not eligible for price difference.
# Moreover, this function is used for standard cost method only.
if (
line.product_id.type != "product"
or line.product_id.valuation != "real_time"
):
continue

# Retrieve accounts needed to generate the price difference.
debit_expense_account = line._get_price_diff_account()
if not debit_expense_account:
continue
# Retrieve stock valuation moves.
valuation_stock_moves = (
self.env["stock.move"].search(
[
("rma_line_id", "=", line.rma_line_id.id),
("state", "=", "done"),
("product_qty", "!=", 0.0),
]
)
if line.rma_line_id
else self.env["stock.move"]
)

if line.product_id.cost_method != "standard" and line.rma_line_id:
if move.move_type == "in_refund":
valuation_stock_moves = valuation_stock_moves.filtered(
lambda stock_move: stock_move._is_out()
)
else:
valuation_stock_moves = valuation_stock_moves.filtered(
lambda stock_move: stock_move._is_in()
)

if not valuation_stock_moves:
continue

(
valuation_price_unit_total,
valuation_total_qty,
) = valuation_stock_moves._get_valuation_price_and_qty(
line, move.currency_id
)
valuation_price_unit = (
valuation_price_unit_total / valuation_total_qty
)
valuation_price_unit = line.product_id.uom_id._compute_price(
valuation_price_unit, line.product_uom_id
)
else:
# Valuation_price unit is always expressed in invoice currency,
# so that it can always be computed with the good rate
price_unit = line.product_id.uom_id._compute_price(
line.product_id.standard_price, line.product_uom_id
)
price_unit = (
-price_unit
if line.move_id.move_type == "in_refund"
else price_unit
)
valuation_date = (
valuation_stock_moves
and max(valuation_stock_moves.mapped("date"))
or move.date
)
valuation_price_unit = line.company_currency_id._convert(
price_unit,
move.currency_id,
move.company_id,
valuation_date,
round=False,
)

price_unit = line._get_gross_unit_price()

price_unit_val_dif = abs(price_unit) - valuation_price_unit
relevant_qty = line.quantity
price_subtotal = relevant_qty * price_unit_val_dif
# We consider there is a price difference if the subtotal is not zero.
# In case a discount has been applied, we can't round the price unit
# anymore, and hence we can't compare them.
if (
not move.currency_id.is_zero(price_subtotal)
and float_compare(
line["price_unit"],
line.price_unit,
precision_digits=price_unit_prec,
)
== 0
):
# Add price difference account line.
vals = {
"name": line.name[:64],
"move_id": move.id,
"partner_id": line.partner_id.id
or move.commercial_partner_id.id,
"currency_id": line.currency_id.id,
"product_id": line.product_id.id,
"product_uom_id": line.product_uom_id.id,
"quantity": relevant_qty,
"price_unit": price_unit_val_dif,
"price_subtotal": relevant_qty * price_unit_val_dif,
"amount_currency": relevant_qty
* price_unit_val_dif
* line.move_id.direction_sign,
"balance": line.currency_id._convert(
relevant_qty
* price_unit_val_dif
* line.move_id.direction_sign,
line.company_currency_id,
line.company_id,
fields.Date.today(),
),
"account_id": debit_expense_account.id,
"analytic_distribution": line.analytic_distribution,
"display_type": "cogs",
"rma_line_id": line.rma_line_id.id,
}

lines_vals_list_rma.append(vals)

# Correct the amount of the current line.
vals = {
"name": line.name[:64],
"move_id": move.id,
"partner_id": line.partner_id.id
or move.commercial_partner_id.id,
"currency_id": line.currency_id.id,
"product_id": line.product_id.id,
"product_uom_id": line.product_uom_id.id,
"quantity": relevant_qty,
"price_unit": -price_unit_val_dif,
"price_subtotal": relevant_qty * -price_unit_val_dif,
"amount_currency": relevant_qty
* -price_unit_val_dif
* line.move_id.direction_sign,
"balance": line.currency_id._convert(
relevant_qty
* -price_unit_val_dif
* line.move_id.direction_sign,
line.company_currency_id,
line.company_id,
fields.Date.today(),
),
"account_id": line.account_id.id,
"analytic_distribution": line.analytic_distribution,
"display_type": "cogs",
"rma_line_id": line.rma_line_id.id,
}
lines_vals_list_rma.append(vals)
rma_refunds |= move
lines_vals_list = super(
AccountMove, self - rma_refunds
)._stock_account_prepare_anglo_saxon_in_lines_vals()
lines_vals_list += lines_vals_list_rma
return lines_vals_list
22 changes: 22 additions & 0 deletions rma_purchase/models/account_move_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from odoo import models


class AccountMoveLine(models.Model):
_inherit = "account.move.line"

def _get_price_diff_account(self):
# force the price difference account to be taken from the price
# different properties as they were in the previous Odoo versions
self.ensure_one()
if self.product_id.cost_method != "standard":
# product variable needed, pre-commit trolling with 88 character
product = self.product_id
debit_pdiff_account = (
product.property_account_creditor_price_difference
or product.categ_id.property_account_creditor_price_difference_categ
)
debit_pdiff_account = self.move_id.fiscal_position_id.map_account(
debit_pdiff_account
)
return debit_pdiff_account
return super()._get_price_diff_account()
15 changes: 15 additions & 0 deletions rma_purchase/models/procurement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2017-2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)

from odoo import fields, models


class ProcurementGroup(models.Model):
_inherit = "procurement.group"

rma_id = fields.Many2one(
comodel_name="rma.order", string="RMA", ondelete="set null"
)
rma_line_id = fields.Many2one(
comodel_name="rma.order.line", string="RMA line", ondelete="set null"
)
30 changes: 30 additions & 0 deletions rma_purchase/models/purchase_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2017-2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)

from odoo import api, models


class PurchaseOrder(models.Model):
_inherit = "purchase.order"

@api.model
def new(self, vals, origin=None, ref=None):
"""Allows to propose a line based on the RMA information."""
res = super().new(vals)
rma_line_id = self.env.context.get("rma_line_id")
if rma_line_id:
rma_line = self.env["rma.order.line"].browse(rma_line_id)
line = self.env["purchase.order.line"].new(
{
"product_id": rma_line.product_id.id,
}
)
line.onchange_product_id()
line.update(
{
"product_qty": rma_line.qty_to_purchase,
"product_uom": rma_line.uom_id.id,
}
)
res.order_line = line
return res
Loading
Loading