mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2026-08-17 16:54:42 -05:00
[PATCH] Upstream patch - 27072022
This commit is contained in:
@@ -5078,7 +5078,7 @@ class AccountMoveLine(models.Model):
|
||||
'ref': self.ref,
|
||||
'move_id': self.id,
|
||||
'user_id': self.move_id.invoice_user_id.id or self._uid,
|
||||
'company_id': distribution.account_id.company_id.id or self.env.company.id,
|
||||
'company_id': distribution.account_id.company_id.id or self.company_id.id or self.env.company.id,
|
||||
}
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -209,9 +209,10 @@ class AccountMove(models.Model):
|
||||
if tax.amount > 0:
|
||||
tax_line += line.price_subtotal * (tax.amount / 100.0)
|
||||
|
||||
invoice_line_unit_price = line.price_unit
|
||||
|
||||
invoice_line_total_price = invoice_line_unit_price * line.quantity
|
||||
discount = 1 - (line.discount / 100)
|
||||
# guarantees price to be tax-excluded
|
||||
invoice_line_total_price = line.price_subtotal / discount if discount else 0
|
||||
invoice_line_unit_price = invoice_line_total_price / line.quantity if line.quantity else 0
|
||||
|
||||
line_dict = {
|
||||
'KODE_OBJEK': line.product_id.default_code or '',
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from . import test_l10n_id_efaktur
|
||||
@@ -0,0 +1,91 @@
|
||||
from flectra.tests import tagged, common
|
||||
from flectra.addons.l10n_id_efaktur.models.account_move import FK_HEAD_LIST, LT_HEAD_LIST, OF_HEAD_LIST, _csv_row
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestIndonesianEfaktur(common.TransactionCase):
|
||||
def setUp(self):
|
||||
"""
|
||||
1) contact with l10n_id_pkp=True, l10n_id_kode_transaksi="01"
|
||||
2) tax: amount=10, type_tax_use=sale, price_include=True
|
||||
3) invoice with partner_id=contact, journal=customer invoices,
|
||||
"""
|
||||
super().setUp()
|
||||
|
||||
self.maxDiff = 1500
|
||||
# change company info for csv detai later
|
||||
self.env.company.country_id = self.env.ref('base.id')
|
||||
self.env.company.street = "test"
|
||||
self.env.company.phone = "12345"
|
||||
|
||||
self.partner_id = self.env['res.partner'].create({"name": "l10ntest", "l10n_id_pkp": True, "l10n_id_kode_transaksi": "01", "l10n_id_nik": "12345"})
|
||||
self.tax_id = self.env['account.tax'].create({"name": "test tax", "type_tax_use": "sale", "amount": 10.0, "price_include": True})
|
||||
|
||||
self.efaktur = self.env['l10n_id_efaktur.efaktur.range'].create({'min': '0000000000001', 'max': '0000000000010'})
|
||||
self.out_invoice_1 = self.env['account.move'].create({
|
||||
'type': 'out_invoice',
|
||||
'partner_id': self.partner_id.id,
|
||||
'invoice_date': '2019-05-01',
|
||||
'date': '2019-05-01',
|
||||
'invoice_line_ids': [
|
||||
(0, 0, {'name': 'line1', 'price_unit': 110.0, 'tax_ids': self.tax_id.ids}),
|
||||
],
|
||||
'l10n_id_kode_transaksi': "01",
|
||||
})
|
||||
self.out_invoice_1.post()
|
||||
|
||||
self.out_invoice_2 = self.env['account.move'].create({
|
||||
'type': 'out_invoice',
|
||||
'partner_id': self.partner_id.id,
|
||||
'invoice_date': '2019-05-01',
|
||||
'date': '2019-05-01',
|
||||
'invoice_line_ids': [
|
||||
(0, 0, {'name': 'line1', 'price_unit': 110.11, 'quantity': 400, 'tax_ids': self.tax_id.ids})
|
||||
],
|
||||
'l10n_id_kode_transaksi': '01'
|
||||
})
|
||||
self.out_invoice_2.post()
|
||||
|
||||
def test_efaktur_csv_output_1(self):
|
||||
"""
|
||||
Test to ensure that the output csv data contains tax-excluded prices regardless of whether the tax configuration is tax-included or tax-excluded.
|
||||
Current test is using price of 110 which is tax-included with tax of amount 10%. So the unit price listed has to be 100 whereas the original result would have 110 instead.
|
||||
"""
|
||||
# to check the diff when test fails
|
||||
|
||||
efaktur_csv_output = self.out_invoice_1._generate_efaktur_invoice(',')
|
||||
output_head = '%s%s%s' % (
|
||||
_csv_row(FK_HEAD_LIST, ','),
|
||||
_csv_row(LT_HEAD_LIST, ','),
|
||||
_csv_row(OF_HEAD_LIST, ','),
|
||||
)
|
||||
# remaining lines
|
||||
line_4 = '"FK","01","0","0000000000001","5","2019","1/5/2019","12345","l10ntest","","100","10","0","","0","110","0","0","INV/2019/0001 12345","0"\n'
|
||||
line_5 = '"FAPR","000000000000000","YourCompany","test","","","","","","","","","","12345"\n'
|
||||
line_6 = '"OF","","","100","1.0","100","0","100","10","0","0"\n'
|
||||
|
||||
efaktur_csv_expected = output_head + line_4 + line_5 + line_6
|
||||
|
||||
self.assertEqual(efaktur_csv_expected, efaktur_csv_output)
|
||||
|
||||
def test_efaktur_csv_output_decimal_place(self):
|
||||
"""
|
||||
Test to ensure that decimal place conversion is only done when inputting to csv
|
||||
This is to test original calculation of invoice_line_total_price: invoice_line_total_price = invoice_line_unit_price * line.quantity
|
||||
as invoice_line_unit_price is already converted to be tax-excluded and set to the decimal place as configured on the currency, the calculation of total could be flawed.
|
||||
|
||||
In this test case, the tax-included price unit is 110.11, hence tax-excluded is 100.1,
|
||||
invoice_line_unit_price will be 100, if we continue with the calculation of total price, it will be 100*400 = 40000
|
||||
eventhough the total is supposed to be 100.1*400 = 40040, there is a 40 discrepancy
|
||||
"""
|
||||
efaktur_csv_output = self.out_invoice_2._generate_efaktur_invoice(',')
|
||||
output_head = '%s%s%s' % (
|
||||
_csv_row(FK_HEAD_LIST, ','),
|
||||
_csv_row(LT_HEAD_LIST, ','),
|
||||
_csv_row(OF_HEAD_LIST, ','),
|
||||
)
|
||||
line_4 = '"FK","01","0","0000000000002","5","2019","1/5/2019","12345","l10ntest","","40040","4004","0","","0","44044","0","0","INV/2019/0002 12345","0"\n'
|
||||
line_5 = '"FAPR","000000000000000","YourCompany","test","","","","","","","","","","12345"\n'
|
||||
line_6 = '"OF","","","100","400.0","40040","0","40040","4004","0","0"\n'
|
||||
|
||||
efaktur_csv_expected = output_head + line_4 + line_5 + line_6
|
||||
self.assertEqual(efaktur_csv_expected, efaktur_csv_output)
|
||||
@@ -3,7 +3,7 @@
|
||||
<record id="l10n_in_view_partner_form" model="ir.ui.view">
|
||||
<field name="name">l10n.in.res.partner.vat.inherit</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="priority" eval="100"/>
|
||||
<field name="priority" eval="90"/>
|
||||
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='vat']" position="attributes">
|
||||
|
||||
@@ -16,7 +16,7 @@ class StockWarehouseOrderpoint(models.Model):
|
||||
def _get_replenishment_order_notification(self):
|
||||
self.ensure_one()
|
||||
domain = [('orderpoint_id', 'in', self.ids)]
|
||||
if self.env.context.get('written_date'):
|
||||
if self.env.context.get('written_after'):
|
||||
domain = AND([domain, [('write_date', '>', self.env.context.get('written_after'))]])
|
||||
production = self.env['mrp.production'].search(domain, limit=1)
|
||||
if production:
|
||||
|
||||
@@ -240,7 +240,7 @@ class Orderpoint(models.Model):
|
||||
def _get_replenishment_order_notification(self):
|
||||
self.ensure_one()
|
||||
domain = [('orderpoint_id', 'in', self.ids)]
|
||||
if self.env.context.get('written_date'):
|
||||
if self.env.context.get('written_after'):
|
||||
domain = AND([domain, [('write_date', '>', self.env.context.get('written_after'))]])
|
||||
order = self.env['purchase.order.line'].search(domain, limit=1).order_id
|
||||
if order:
|
||||
|
||||
@@ -429,7 +429,7 @@ class StockWarehouseOrderpoint(models.Model):
|
||||
def _get_replenishment_order_notification(self):
|
||||
self.ensure_one()
|
||||
domain = [('orderpoint_id', 'in', self.ids)]
|
||||
if self.env.context.get('written_date'):
|
||||
if self.env.context.get('written_after'):
|
||||
domain = expression.AND([domain, [('write_date', '>', self.env.context.get('written_after'))]])
|
||||
move = self.env['stock.move'].search(domain, limit=1)
|
||||
if move.picking_id:
|
||||
|
||||
@@ -1439,7 +1439,7 @@ var VideoWidget = MediaWidget.extend({
|
||||
type = 'vine';
|
||||
} else if (matches.vimeo && matches.vimeo[3].length) {
|
||||
const vimeoAutoplay = autoplay.replace('mute', 'muted');
|
||||
embedURL = `//player.vimeo.com/video/${matches.vimeo[3]}${vimeoAutoplay}${loop}`;
|
||||
embedURL = `//player.vimeo.com/video/${matches.vimeo[3]}${vimeoAutoplay}${loop}${controls}`;
|
||||
type = 'vimeo';
|
||||
} else if (matches.dailymotion && matches.dailymotion[2].length) {
|
||||
const videoId = matches.dailymotion[2].replace('video/', '');
|
||||
|
||||
@@ -653,6 +653,9 @@ blockquote {
|
||||
}
|
||||
}
|
||||
}
|
||||
.dropdown-menu .dropdown-item-text .text-muted {
|
||||
color: $text-muted !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@for $index from 1 through length($o-color-combinations) {
|
||||
|
||||
@@ -572,6 +572,7 @@ $o-color-extras-nesting-selector: '&, .o_colored_level &';
|
||||
@if type-of($-related-color) == 'number' {
|
||||
// This is a preset to be applied, just extend it. This should probably
|
||||
// be avoided and use the class in XML if possible.
|
||||
@extend .o_cc;
|
||||
@extend .o_cc#{$-related-color};
|
||||
} @else {
|
||||
@include o-bg-color(o-color($-related-color), $with-extras: $with-extras, $background: $background, $important: false);
|
||||
|
||||
@@ -426,7 +426,7 @@
|
||||
<div class="o_youtube_option o_vimeo_option">
|
||||
<label class="o_switch mb0"><input id="o_video_loop" type="checkbox"/><span/>Loop</label>
|
||||
</div>
|
||||
<div class="o_youtube_option o_dailymotion_option">
|
||||
<div class="o_youtube_option o_dailymotion_option o_vimeo_option">
|
||||
<label class="o_switch mb0"><input id="o_video_hide_controls" type="checkbox"/><span/>Hide player controls</label>
|
||||
</div>
|
||||
<div class="o_youtube_option">
|
||||
|
||||
@@ -110,6 +110,17 @@ publicWidget.registry.productsSearchBar = publicWidget.Widget.extend({
|
||||
currency: res['currency'],
|
||||
widget: this,
|
||||
}));
|
||||
|
||||
// TODO adapt directly in the template in master
|
||||
const mutedItemTextEl = this.$menu.find('span.dropdown-item-text.text-muted')[0];
|
||||
if (mutedItemTextEl) {
|
||||
const newItemTextEl = document.createElement('span');
|
||||
newItemTextEl.classList.add('dropdown-item-text');
|
||||
mutedItemTextEl.after(newItemTextEl);
|
||||
mutedItemTextEl.classList.remove('dropdown-item-text');
|
||||
newItemTextEl.appendChild(mutedItemTextEl);
|
||||
}
|
||||
|
||||
this.$menu.css('min-width', this.autocompleteMinWidth);
|
||||
|
||||
// Handle the case where the searchbar is in a mega menu by making
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
<div t-name="website_sale.productsSearchBar.autocomplete"
|
||||
class="dropdown-menu show w-100">
|
||||
<t t-if="!products.length">
|
||||
<!-- TODO adapt in master, this is patched in JS so that text-muted -->
|
||||
<!-- is not on the same element as dropdown-item-text -->
|
||||
<span class="dropdown-item-text text-muted">No results found. Please try another search.</span>
|
||||
</t>
|
||||
<a t-foreach="products" t-as="product"
|
||||
|
||||
@@ -94,6 +94,19 @@ $o-wslides-fs-side-width: 300px;
|
||||
.o_wslides_home_nav {
|
||||
top: -40px;
|
||||
|
||||
// TODO Remove me in master
|
||||
[style*="background: white"] .nav-link {
|
||||
color: $navbar-light-color !important;
|
||||
|
||||
@include hover-focus {
|
||||
color: $navbar-light-hover-color !important;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: $navbar-light-disabled-color !important;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
font-size: 1rem;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<div class="container mt16 o_wslides_home_nav position-relative">
|
||||
<!-- TODO Remove inline style in master -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light shadow-sm" style="background: white!important">
|
||||
<form method="GET" class="form-inline o_wslides_nav_navbar_right order-lg-3" t-attf-action="/slides/all" role="search">
|
||||
<div class="input-group">
|
||||
@@ -181,6 +182,7 @@
|
||||
</section>
|
||||
<div class="container mt16 o_wslides_home_nav position-relative">
|
||||
<!-- Navbar dynamically composed using displayed channel tag groups. -->
|
||||
<!-- TODO Remove inline style in master -->
|
||||
<nav class="navbar navbar-expand-md navbar-light shadow-sm pl-0" style="background: white!important">
|
||||
<div class="navbar-nav border-right">
|
||||
<a class="nav-link nav-item px-3" href="/slides"><i class="fa fa-chevron-left"/></a>
|
||||
|
||||
Reference in New Issue
Block a user