Skip to content

Commit

Permalink
[ADD] Improve stock price calc and usability
Browse files Browse the repository at this point in the history
  • Loading branch information
DiegoParadeda committed Jul 11, 2024
1 parent 61d617f commit 7acfd15
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 41 deletions.
81 changes: 60 additions & 21 deletions l10n_br_fiscal/models/stock_price_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,81 @@ class StockPriceMixin(models.AbstractModel):
_name = "l10n_br_fiscal.stock.price.mixin"
_description = "Stock Price Mixin"

freight_value_to_stock = fields.Boolean(
string="freight_value_to_stock",
default=True,
)

insurance_value_to_stock = fields.Boolean(
string="insurance_value_to_stock",
default=True,
)

other_value_to_stock = fields.Boolean(
string="other_value_to_stock",
default=True,
)

issqn_tax_is_creditable = fields.Boolean(
string="ISSQN Creditável",
default=False,
default=lambda self: self.valuation_via_stock_price,
)

irpj_tax_is_creditable = fields.Boolean(
string="IRPJ Creditável",
default=False,
default=lambda self: self.valuation_via_stock_price,
)

icmsst_tax_is_creditable = fields.Boolean(
string="ICMS ST Creditável",
default=False,
default=lambda self: self.valuation_via_stock_price,
)

icms_tax_is_creditable = fields.Boolean(string="ICMS Creditável")
ipi_tax_is_creditable = fields.Boolean(string="IPI Creditável")
cofins_tax_is_creditable = fields.Boolean(string="COFINS Creditável")
pis_tax_is_creditable = fields.Boolean(string="PIS Creditável")
icms_tax_is_creditable = fields.Boolean(
string="ICMS Creditável",
default=lambda self: self.valuation_via_stock_price,
)
ipi_tax_is_creditable = fields.Boolean(
string="IPI Creditável",
default=lambda self: self.valuation_via_stock_price,
)
cofins_tax_is_creditable = fields.Boolean(
string="COFINS Creditável",
default=lambda self: self.valuation_via_stock_price,
)
pis_tax_is_creditable = fields.Boolean(
string="PIS Creditável",
default=lambda self: self.valuation_via_stock_price,
)

@api.onchange("icms_cst_id")
def _onchange_icms_cst_id(self):
self.icms_tax_is_creditable = self.icms_cst_id.default_creditable_tax
if self.valuation_via_stock_price:
self.icms_tax_is_creditable = self.icms_cst_id.default_creditable_tax

@api.onchange("ipi_cst_id")
def _onchange_ipi_cst_id(self):
self.ipi_tax_is_creditable = self.ipi_cst_id.default_creditable_tax
if self.valuation_via_stock_price:
self.ipi_tax_is_creditable = self.ipi_cst_id.default_creditable_tax

@api.onchange("cofins_cst_id")
def _onchange_cofins_cst_id(self):
self.cofins_tax_is_creditable = self.cofins_cst_id.default_creditable_tax
if self.valuation_via_stock_price:
self.cofins_tax_is_creditable = self.cofins_cst_id.default_creditable_tax

@api.onchange("pis_cst_id")
def _onchange_pis_cst_id(self):
self.pis_tax_is_creditable = self.pis_cst_id.default_creditable_tax
if self.valuation_via_stock_price:
self.pis_tax_is_creditable = self.pis_cst_id.default_creditable_tax

def _default_valuation_stock_price(self):
"""
Método para chavear o custo médio dos produtos entre:
- líquido de impostos
- com impostos (padrão do Odoo).
TODO: Posicionar o campo para o usuário poder interagir com esse chaveamento
a nível de company
"""
return True
company_default = self.company_id.stock_valuation_via_stock_price
return company_default

valuation_via_stock_price = fields.Boolean(
string="Valuation Via Stock Price",
Expand All @@ -63,14 +93,16 @@ def _default_valuation_stock_price(self):
" * Usar True para valor de estoque líquido (sem imposto)",
)

currency_id = fields.Many2one(
stock_price_br_currency_id = fields.Many2one(
comodel_name="res.currency",
string="Currency",
default=lambda self: self.env.ref("base.BRL"),
)

stock_price_br = fields.Monetary(
string="Stock Price", compute="_compute_stock_price_br"
string="Stock Price",
compute="_compute_stock_price_br",
currency_field="stock_price_br_currency_id",
)

@api.depends(
Expand All @@ -84,6 +116,9 @@ def _default_valuation_stock_price(self):
"ipi_tax_is_creditable",
"cofins_tax_is_creditable",
"pis_tax_is_creditable",
"freight_value_to_stock",
"insurance_value_to_stock",
"other_value_to_stock",
)
def _compute_stock_price_br(self):
"""Subtract creditable taxes from stock price."""
Expand All @@ -96,18 +131,22 @@ def _compute_stock_price_br(self):
if record.fiscal_operation_line_id and record.product_uom_qty:
price = record.amount_total

if not record.valuation_via_stock_price:
continue
if not record.freight_value_to_stock:
price -= record.freight_value

Check warning on line 135 in l10n_br_fiscal/models/stock_price_mixin.py

View check run for this annotation

Codecov / codecov/patch

l10n_br_fiscal/models/stock_price_mixin.py#L135

Added line #L135 was not covered by tests
if not record.insurance_value_to_stock:
price -= record.insurance_value

Check warning on line 137 in l10n_br_fiscal/models/stock_price_mixin.py

View check run for this annotation

Codecov / codecov/patch

l10n_br_fiscal/models/stock_price_mixin.py#L137

Added line #L137 was not covered by tests
if not record.other_value_to_stock:
price -= record.other_value

Check warning on line 139 in l10n_br_fiscal/models/stock_price_mixin.py

View check run for this annotation

Codecov / codecov/patch

l10n_br_fiscal/models/stock_price_mixin.py#L139

Added line #L139 was not covered by tests

for tax in record.fiscal_tax_ids:
if hasattr(record, "%s_tax_is_creditable" % (tax.tax_domain,)):
try:
creditable = getattr(
record, "%s_tax_is_creditable" % (tax.tax_domain,)
)
if creditable:
if not hasattr(record, "%s_value" % (tax.tax_domain)):
continue
price -= getattr(record, "%s_value" % (tax.tax_domain))
except AttributeError:
pass

price_precision = self.env["decimal.precision"].precision_get(
"Product Price"
Expand Down
13 changes: 13 additions & 0 deletions l10n_br_purchase_stock/models/purchase_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ class PurchaseOrder(models.Model):
compute="_compute_get_button_create_invoice_invisible"
)

total_cost_of_goods_purchased = fields.Monetary(
string="Cost of Goods Purchased",
compute="_compute_cogp_amount",
)

@api.depends("order_line", "order_line.stock_price_br")
def _compute_cogp_amount(self):
for record in self:
cogp = 0
for line in record.order_line:
cogp += line.stock_price_br
record.total_cost_of_goods_purchased = cogp

@api.depends("state", "invoice_status")
def _compute_get_button_create_invoice_invisible(self):
for record in self:
Expand Down
71 changes: 61 additions & 10 deletions l10n_br_purchase_stock/views/purchase_order.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,69 @@

</xpath>

<xpath
expr="//field[@name='order_line']//form//notebook//field[@name='other_value']"
position="after"
>
<field
name="stock_price_br"
attrs="{'readonly': [('delivery_costs', '=', 'total')]}"
/>

<xpath expr="//field[@name='amount_tax_withholding']" position="after">
<field name="total_cost_of_goods_purchased" />
</xpath>

<xpath expr="//page[@name='others']" position="inside">
<xpath expr="//field[@name='delivery_costs']/.." position="replace">
<group>
<field name="stock_price_br" readonly="1" />
</group>

<group>
<field name="delivery_costs" invisible="1" />
</group>

<group col="4">
<field
name="freight_value"
attrs="{'readonly': [('delivery_costs', '=', 'total')]}"
/>
<div class="o_row">
<field name="freight_value_to_stock" nolabel="1" />
<span
attrs="{'invisible': [('freight_value_to_stock', '=', True)]}"
class="text-muted"
>Frete é custo de estoque?</span>
<span
attrs="{'invisible': [('freight_value_to_stock', '=', False)]}"
>Frete
é custo de estoque?</span>
</div>

<field
name="insurance_value"
attrs="{'readonly': [('delivery_costs', '=', 'total')]}"
/>
<div class="o_row">
<field name="insurance_value_to_stock" nolabel="1" />
<span
attrs="{'invisible': [('insurance_value_to_stock', '=', True)]}"
class="text-muted"
>Seguro é custo de estoque?</span>
<span
attrs="{'invisible': [('insurance_value_to_stock', '=', False)]}"
>Seguro
é custo de estoque?</span>
</div>

<field
name="other_value"
attrs="{'readonly': [('delivery_costs', '=', 'total')]}"
/>
<div class="o_row">
<field name="other_value_to_stock" nolabel="1" />
<span
attrs="{'invisible': [('other_value_to_stock', '=', True)]}"
class="text-muted"
>Outras.Desp. é custo de estoque?</span>
<span
attrs="{'invisible': [('other_value_to_stock', '=', False)]}"
>Outras.Desp.
é custo de estoque?</span>
</div>
</group>

<group name="tax_credits" string="Tax Credits">
<group>
<field name="icms_tax_is_creditable" />
Expand Down
8 changes: 8 additions & 0 deletions l10n_br_stock_account/models/res_company.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ class ResCompany(models.Model):
comodel_name="l10n_br_fiscal.operation",
domain=[("state", "=", "approved"), ("fiscal_operation_type", "=", "out")],
)

stock_valuation_via_stock_price = fields.Boolean(
string="Valuation Via Stock Price",
default=True,
help="Determina se o valor utilizado no custeamento automático será padrão do"
" Odoo ou com base no campo stock_price_br.\n\n"
" * Usar True para valor de estoque líquido (sem imposto)",
)
5 changes: 1 addition & 4 deletions l10n_br_stock_account/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,7 @@ def _get_price_unit(self):
# e continua sendo feito abaixo?
if self.fiscal_operation_id.fiscal_operation_type == "out":
result = self.product_id.with_company(self.company_id).standard_price
elif (
self.fiscal_operation_id.fiscal_operation_type == "in"
and self.valuation_via_stock_price
):
elif self.fiscal_operation_id.fiscal_operation_type == "in":
result = self.stock_price_br

return result
Expand Down
1 change: 1 addition & 0 deletions l10n_br_stock_account/views/res_company_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<field name="stock_fiscal_operation_id" />
<field name="stock_in_fiscal_operation_id" />
<field name="stock_out_fiscal_operation_id" />
<field name="stock_valuation_via_stock_price" />
</group>
</group>
</page>
Expand Down
52 changes: 46 additions & 6 deletions l10n_br_stock_account/views/stock_picking.xml
Original file line number Diff line number Diff line change
Expand Up @@ -128,23 +128,64 @@
</group>
<page name="fiscal_taxes" string="Taxes" />
<page name="others" string="Others">
<group>
<field name="stock_price_br" readonly="1" />
</group>

<group>
<field name="delivery_costs" invisible="1" />
</group>

<group col="4">
<field
name="freight_value"
attrs="{'readonly': [('delivery_costs', '=', 'total')]}"
/>
<div class="o_row">
<field name="freight_value_to_stock" nolabel="1" />
<span
attrs="{'invisible': [('freight_value_to_stock', '=', True)]}"
class="text-muted"
>Frete é custo de estoque?</span>
<span
attrs="{'invisible': [('freight_value_to_stock', '=', False)]}"
>Frete é custo de estoque?</span>
</div>

<field
name="insurance_value"
attrs="{'readonly': [('delivery_costs', '=', 'total')]}"
/>
<div class="o_row">
<field
name="insurance_value_to_stock"
nolabel="1"
/>
<span
attrs="{'invisible': [('insurance_value_to_stock', '=', True)]}"
class="text-muted"
>Seguro é custo de estoque?</span>
<span
attrs="{'invisible': [('insurance_value_to_stock', '=', False)]}"
>Seguro é custo de estoque?</span>
</div>

<field
name="other_value"
attrs="{'readonly': [('delivery_costs', '=', 'total')]}"
/>
<field name="stock_price_br" readonly="1" />
<field name="valuation_via_stock_price" />
<div class="o_row">
<field name="other_value_to_stock" nolabel="1" />
<span
attrs="{'invisible': [('other_value_to_stock', '=', True)]}"
class="text-muted"
>Outras.Desp. é custo de estoque?</span>
<span
attrs="{'invisible': [('other_value_to_stock', '=', False)]}"
>Outras.Desp. é custo de estoque?</span>
</div>
</group>

<group name="tax_credits" string="Tax Credits">
<group>
<field name="icms_tax_is_creditable" />
Expand Down Expand Up @@ -210,26 +251,25 @@
<field name="invoice_line_ids" readonly="1" nolabel="1" />
</group>


</xpath>
<xpath expr="//page[@name='extra']/group" position="inside">
<group name="delivery_costs" string="Delivery Costs">
<field name="delivery_costs" invisible="1" />
<field
name="amount_freight_value"
widget='monetary'
widget="monetary"
options="{'currency_field': 'currency_id'}"
attrs="{'readonly': [('delivery_costs', '=', 'line')]}"
/>
<field
name="amount_insurance_value"
widget='monetary'
widget="monetary"
options="{'currency_field': 'currency_id'}"
attrs="{'readonly': [('delivery_costs', '=', 'line')]}"
/>
<field
name="amount_other_value"
widget='monetary'
widget="monetary"
options="{'currency_field': 'currency_id'}"
attrs="{'readonly': [('delivery_costs', '=', 'line')]}"
/>
Expand Down

0 comments on commit 7acfd15

Please sign in to comment.