mirror of
https://github.com/bringout/oca-workflow-process.git
synced 2026-04-23 05:52:00 +02:00
Initial commit: OCA Workflow Process packages (456 packages)
This commit is contained in:
commit
d366e42934
18799 changed files with 1284507 additions and 0 deletions
|
|
@ -0,0 +1,5 @@
|
|||
# Copyright 2019 Elico Corp, Dominique K. <dominique.k@elico-corp.com.sg>
|
||||
# Copyright 2019 Ecosoft Co., Ltd., Kitti U. <kittiu@ecosoft.co.th>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import purchase_make_invoice_advance
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
# Copyright 2019 Elico Corp, Dominique K. <dominique.k@elico-corp.com.sg>
|
||||
# Copyright 2019 Ecosoft Co., Ltd., Kitti U. <kittiu@ecosoft.co.th>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
||||
|
||||
class PurchaseAdvancePaymentInv(models.TransientModel):
|
||||
_name = "purchase.advance.payment.inv"
|
||||
_description = "Purchase Advance Payment Invoice"
|
||||
|
||||
advance_payment_method = fields.Selection(
|
||||
[
|
||||
("percentage", "Deposit payment (percentage)"),
|
||||
("fixed", "Deposit payment (fixed amount)"),
|
||||
],
|
||||
string="What do you want to invoice?",
|
||||
default="percentage",
|
||||
required=True,
|
||||
)
|
||||
purchase_deposit_product_id = fields.Many2one(
|
||||
comodel_name="product.product",
|
||||
string="Deposit Payment Product",
|
||||
domain=[("type", "=", "service")],
|
||||
default=lambda self: self.env.company.purchase_deposit_product_id,
|
||||
)
|
||||
amount = fields.Float(
|
||||
string="Deposit Payment Amount",
|
||||
required=True,
|
||||
help="The amount to be invoiced in advance, taxes excluded.",
|
||||
)
|
||||
deposit_account_id = fields.Many2one(
|
||||
comodel_name="account.account",
|
||||
string="Expense Account",
|
||||
compute="_compute_deposit_account_id",
|
||||
store=True,
|
||||
readonly=False,
|
||||
domain=[("deprecated", "=", False)],
|
||||
help="Account used for deposits",
|
||||
)
|
||||
deposit_taxes_id = fields.Many2many(
|
||||
comodel_name="account.tax",
|
||||
string="Vendor Taxes",
|
||||
compute="_compute_deposit_account_id",
|
||||
store=True,
|
||||
readonly=False,
|
||||
help="Taxes used for deposits",
|
||||
)
|
||||
|
||||
@api.depends("purchase_deposit_product_id")
|
||||
def _compute_deposit_account_id(self):
|
||||
product = self.purchase_deposit_product_id
|
||||
self.deposit_account_id = product.property_account_expense_id
|
||||
self.deposit_taxes_id = product.supplier_taxes_id
|
||||
|
||||
def _prepare_deposit_val(self, order, po_line, amount):
|
||||
ir_property_obj = self.env["ir.property"]
|
||||
account_id = False
|
||||
product = self.purchase_deposit_product_id
|
||||
if product.id:
|
||||
account_id = (
|
||||
product.property_account_expense_id.id
|
||||
or product.categ_id.property_account_expense_categ_id.id
|
||||
)
|
||||
if not account_id:
|
||||
inc_acc = ir_property_obj._get(
|
||||
"property_account_expense_categ_id", "product.category"
|
||||
)
|
||||
account_id = (
|
||||
order.fiscal_position_id.map_account(inc_acc).id if inc_acc else False
|
||||
)
|
||||
if not account_id:
|
||||
raise UserError(
|
||||
_(
|
||||
"There is no purchase account defined for this product: %s."
|
||||
"\nYou may have to install a chart of account from "
|
||||
"Accounting app, settings menu."
|
||||
)
|
||||
% (product.name,)
|
||||
)
|
||||
|
||||
if self.amount <= 0:
|
||||
raise UserError(_("The value of the deposit must be positive."))
|
||||
context = {"lang": order.partner_id.lang}
|
||||
amount = self.amount
|
||||
if self.advance_payment_method == "percentage": # Case percent
|
||||
if self.amount > 100:
|
||||
raise UserError(_("The percentage of the deposit must be not over 100"))
|
||||
amount = self.amount / 100 * order.amount_untaxed
|
||||
name = _("Deposit Payment")
|
||||
del context
|
||||
taxes = product.supplier_taxes_id.filtered(
|
||||
lambda r: not order.company_id or r.company_id == order.company_id
|
||||
)
|
||||
if order.fiscal_position_id and taxes:
|
||||
tax_ids = order.fiscal_position_id.map_tax(taxes).ids
|
||||
else:
|
||||
tax_ids = taxes.ids
|
||||
|
||||
deposit_val = {
|
||||
"invoice_origin": order.name,
|
||||
"move_type": "in_invoice",
|
||||
"partner_id": order.partner_id.id,
|
||||
"invoice_line_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": name,
|
||||
"account_id": account_id,
|
||||
"price_unit": amount,
|
||||
"quantity": 1.0,
|
||||
"product_uom_id": product.uom_id.id,
|
||||
"product_id": product.id,
|
||||
"purchase_line_id": po_line.id,
|
||||
"tax_ids": [(6, 0, tax_ids)],
|
||||
"analytic_distribution": po_line.analytic_distribution,
|
||||
},
|
||||
)
|
||||
],
|
||||
"currency_id": order.currency_id.id,
|
||||
"invoice_payment_term_id": order.payment_term_id.id,
|
||||
"fiscal_position_id": order.fiscal_position_id.id
|
||||
or order.partner_id.property_account_position_id.id,
|
||||
"purchase_id": order.id,
|
||||
"narration": order.notes,
|
||||
}
|
||||
return deposit_val
|
||||
|
||||
def _create_invoice(self, order, po_line, amount):
|
||||
Invoice = self.env["account.move"]
|
||||
deposit_val = self._prepare_deposit_val(order, po_line, amount)
|
||||
invoice = Invoice.create(deposit_val)
|
||||
invoice.message_post_with_view(
|
||||
"mail.message_origin_link",
|
||||
values={"self": invoice, "origin": order},
|
||||
subtype_id=self.env.ref("mail.mt_note").id,
|
||||
)
|
||||
return invoice
|
||||
|
||||
def _prepare_advance_purchase_line(self, order, product, tax_ids, amount):
|
||||
return {
|
||||
"name": _("Advance: %s") % (time.strftime("%m %Y"),),
|
||||
"price_unit": amount,
|
||||
"product_qty": 0.0,
|
||||
"order_id": order.id,
|
||||
"product_uom": product.uom_id.id,
|
||||
"product_id": product.id,
|
||||
"taxes_id": [(6, 0, tax_ids)],
|
||||
"date_planned": datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
"is_deposit": True,
|
||||
"sequence": order.order_line
|
||||
and order.order_line[-1].sequence + 1
|
||||
or self.env["purchase.order.line"]
|
||||
.default_get(["sequence"])
|
||||
.get("sequence"),
|
||||
}
|
||||
|
||||
def _prepare_advance_purchase_section_values(self, order):
|
||||
context = {"lang": order.partner_id.lang}
|
||||
so_values = {
|
||||
"name": _("Purchase Deposits"),
|
||||
"product_qty": 0.0,
|
||||
"order_id": order.id,
|
||||
"display_type": "line_section",
|
||||
"is_deposit": True,
|
||||
"sequence": order.order_line
|
||||
and order.order_line[-1].sequence + 1
|
||||
or self.env["purchase.order.line"]
|
||||
.default_get(["sequence"])
|
||||
.get("sequence"),
|
||||
}
|
||||
del context
|
||||
return so_values
|
||||
|
||||
def create_invoices(self):
|
||||
Purchase = self.env["purchase.order"]
|
||||
purchases = Purchase.browse(self._context.get("active_ids", []))
|
||||
# Create deposit product if necessary
|
||||
product = self.purchase_deposit_product_id
|
||||
if not product:
|
||||
vals = self._prepare_deposit_product()
|
||||
product = self.purchase_deposit_product_id = (
|
||||
self.env["product.product"].sudo().create(vals)
|
||||
)
|
||||
self.env.company.sudo().purchase_deposit_product_id = product
|
||||
PurchaseLine = self.env["purchase.order.line"]
|
||||
for order in purchases:
|
||||
amount = self.amount
|
||||
if self.advance_payment_method == "percentage": # Case percent
|
||||
amount = self.amount / 100 * order.amount_untaxed
|
||||
if product.purchase_method != "purchase":
|
||||
raise UserError(
|
||||
_(
|
||||
"The product used to invoice a down payment should have "
|
||||
'an invoice policy set to "Ordered quantities". '
|
||||
"Please update your deposit product to be able to "
|
||||
"create a deposit invoice."
|
||||
)
|
||||
)
|
||||
if product.type != "service":
|
||||
raise UserError(
|
||||
_(
|
||||
"The product used to invoice a down payment should be "
|
||||
'of type "Service". Please use another product or '
|
||||
"update this product."
|
||||
)
|
||||
)
|
||||
taxes = product.supplier_taxes_id.filtered(
|
||||
lambda r: not order.company_id or r.company_id == order.company_id
|
||||
)
|
||||
if order.fiscal_position_id and taxes:
|
||||
tax_ids = order.fiscal_position_id.map_tax(taxes).ids
|
||||
else:
|
||||
tax_ids = taxes.ids
|
||||
context = {"lang": order.partner_id.lang}
|
||||
if not any(
|
||||
line.display_type and line.is_deposit for line in order.order_line
|
||||
):
|
||||
PurchaseLine.create(
|
||||
self._prepare_advance_purchase_section_values(order)
|
||||
)
|
||||
adv_po_line_dict = self._prepare_advance_purchase_line(
|
||||
order, product, tax_ids, amount
|
||||
)
|
||||
po_line = PurchaseLine.create(adv_po_line_dict)
|
||||
del context
|
||||
self._create_invoice(order, po_line, amount)
|
||||
if self._context.get("open_bills", False):
|
||||
return purchases.action_view_invoice()
|
||||
return {"type": "ir.actions.act_window_close"}
|
||||
|
||||
def _prepare_deposit_product(self):
|
||||
return {
|
||||
"name": "Purchase Deposit",
|
||||
"type": "service",
|
||||
"purchase_method": "purchase",
|
||||
"property_account_expense_id": self.deposit_account_id.id,
|
||||
"supplier_taxes_id": [(6, 0, self.deposit_taxes_id.ids)],
|
||||
"company_id": False,
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record id="view_purchase_advance_payment_inv" model="ir.ui.view">
|
||||
<field name="name">Invoice Orders</field>
|
||||
<field name="model">purchase.advance.payment.inv</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Invoice Purchases Order">
|
||||
<p class="oe_grey">
|
||||
Invoices will be created in draft so that you can review them before validation.
|
||||
</p>
|
||||
<group>
|
||||
<field
|
||||
name="advance_payment_method"
|
||||
class="oe_inline"
|
||||
widget="radio"
|
||||
/>
|
||||
<field
|
||||
name="purchase_deposit_product_id"
|
||||
invisible="1"
|
||||
class="oe_inline"
|
||||
context="{'search_default_services': 1, 'default_type': 'service', 'default_invoice_policy': 'order'}"
|
||||
/>
|
||||
<label for="amount" />
|
||||
<div>
|
||||
<field name="amount" class="oe_inline" widget="monetary" />
|
||||
<span
|
||||
attrs="{'invisible': [('advance_payment_method', '!=', 'percentage')]}"
|
||||
class="oe_inline"
|
||||
>%</span>
|
||||
</div>
|
||||
<field
|
||||
name="deposit_account_id"
|
||||
class="oe_inline"
|
||||
attrs="{'invisible': [('purchase_deposit_product_id', '!=', False)]}"
|
||||
/>
|
||||
<field
|
||||
name="deposit_taxes_id"
|
||||
class="oe_inline"
|
||||
widget="many2many_tags"
|
||||
domain="[('type_tax_use','=','purchase')]"
|
||||
attrs="{'invisible': [('purchase_deposit_product_id', '!=', False)]}"
|
||||
/>
|
||||
</group>
|
||||
<footer>
|
||||
<button
|
||||
name="create_invoices"
|
||||
string="Create and View bills"
|
||||
type="object"
|
||||
context="{'open_bills': True}"
|
||||
class="btn-primary"
|
||||
/>
|
||||
<button
|
||||
name="create_invoices"
|
||||
string="Create Bill"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
/>
|
||||
<button string="Cancel" class="btn-default" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_view_purchase_advance_payment_inv" model="ir.actions.act_window">
|
||||
<field name="name">Invoice Order</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">purchase.advance.payment.inv</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue