mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2026-08-19 01:34:43 -05:00
[PATCH] Upstream patch
This commit is contained in:
@@ -3603,7 +3603,7 @@ class AccountMoveLine(models.Model):
|
||||
# ONCHANGE METHODS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@api.onchange('amount_currency', 'currency_id', 'debit', 'credit', 'tax_ids', 'account_id', 'price_unit')
|
||||
@api.onchange('amount_currency', 'currency_id', 'debit', 'credit', 'tax_ids', 'account_id', 'price_unit', 'quantity')
|
||||
def _onchange_mark_recompute_taxes(self):
|
||||
''' Recompute the dynamic onchange based on taxes.
|
||||
If the edited line is a tax line, don't recompute anything as the user must be able to
|
||||
@@ -4907,7 +4907,7 @@ class AccountMoveLine(models.Model):
|
||||
'move_id': move_line.id,
|
||||
'user_id': move_line.move_id.invoice_user_id.id or self._uid,
|
||||
'partner_id': move_line.partner_id.id,
|
||||
'company_id': move_line.analytic_account_id.company_id.id or self.env.company.id,
|
||||
'company_id': move_line.analytic_account_id.company_id.id or move_line.move_id.company_id.id,
|
||||
})
|
||||
return result
|
||||
|
||||
|
||||
@@ -183,7 +183,9 @@ class AccountTax(models.Model):
|
||||
|
||||
@api.returns('self', lambda value: value.id)
|
||||
def copy(self, default=None):
|
||||
default = dict(default or {}, name=_("%s (Copy)", self.name))
|
||||
default = dict(default or {})
|
||||
if 'name' not in default:
|
||||
default['name'] = _("%s (Copy)") % self.name
|
||||
return super(AccountTax, self).copy(default=default)
|
||||
|
||||
def name_get(self):
|
||||
|
||||
@@ -168,10 +168,11 @@ class AccountFiscalPosition(models.Model):
|
||||
# This can be easily overridden to apply more complex fiscal rules
|
||||
PartnerObj = self.env['res.partner']
|
||||
partner = PartnerObj.browse(partner_id)
|
||||
delivery = PartnerObj.browse(delivery_id)
|
||||
|
||||
# If partner and delivery have the same vat prefix, use invoicing
|
||||
if not delivery or (delivery.vat and partner.vat and delivery.vat[:2] == partner.vat[:2]):
|
||||
# if no delivery use invoicing
|
||||
if delivery_id:
|
||||
delivery = PartnerObj.browse(delivery_id)
|
||||
else:
|
||||
delivery = partner
|
||||
|
||||
# partner manually set fiscal position always win
|
||||
|
||||
@@ -1,6 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<flectra>
|
||||
<data noupdate="0">
|
||||
<!--
|
||||
There are 4 groups
|
||||
The way the groups work is different when `account_accountant` is installed or not.
|
||||
|
||||
Invoicing only:
|
||||
```
|
||||
group_account_invoice ⇨ group_account_manager (only those two should be used)
|
||||
⬂
|
||||
group_account_readonly ⇨ group_account_user (those two are only visible in debug)
|
||||
```
|
||||
|
||||
Invoicing + Accounting:
|
||||
```
|
||||
group_account_invoice ⬂
|
||||
group_account_readonly ⇨ group_account_user ⇨ group_account_manager
|
||||
```
|
||||
`group_account_user` is almost (a bit more than) the sum of `group_account_invoice` and `group_account_readonly`
|
||||
`group_account_manager` is the king (except when Consolidation is installed, then there is a super-king)
|
||||
|
||||
`group_account_invoice` can create/edit invoices, refunds, payments, etc but cannot see accounting related stuff (journal entries, reports, reconciliation,...)
|
||||
`group_account_readonly` can see (and only see) everything, including the journal entries, advanced configuration, reports
|
||||
`group_account_user` is the accountant: he can do everything except advanced config (accounting periods for instance)
|
||||
`group_account_manager` can edit some config that `group_account_user` cannot do
|
||||
|
||||
When you have only Invoicing installed, only `group_account_invoice` and `group_account_manager` should be used. The others are giving a shallow access to Accounting features, but we want to remove that.
|
||||
-->
|
||||
|
||||
<record model="ir.module.category" id="base.module_category_accounting_accounting">
|
||||
<field name="description">Helps you handle your accounting needs, if you are not an accountant, we suggest you to install only the Invoicing.</field>
|
||||
|
||||
@@ -154,15 +154,3 @@ class TestFiscalPosition(common.SavepointCase):
|
||||
mapped_taxes = self.fp2m.map_tax(self.src_tax)
|
||||
|
||||
self.assertEqual(mapped_taxes, self.dst1_tax | self.dst2_tax)
|
||||
|
||||
def test_30_fp_country_delivery(self):
|
||||
"""
|
||||
Customer is in Belgium
|
||||
Delivery is in France
|
||||
Check if fiscal position is France
|
||||
"""
|
||||
self.george.vat = False
|
||||
self.assertEqual(
|
||||
self.fp.get_fiscal_position(self.ben.id, self.george.id).id,
|
||||
self.fr_b2c.id,
|
||||
"FR B2C should be set")
|
||||
|
||||
@@ -823,7 +823,7 @@
|
||||
<filter string="Won" name="won" domain="['&', ('active', '=', True), ('stage_id.is_won', '=', True)]"/>
|
||||
<filter string="Lost" name="lost" domain="['&', ('active', '=', False), ('probability', '=', 0)]"/>
|
||||
<separator/>
|
||||
<filter invisible="1" string="Overdue Opportunities" name="overdue_opp" domain="[('date_deadline', '<', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter invisible="1" string="Overdue Opportunities" name="overdue_opp" domain="['&', ('date_closed', '=', False), ('date_deadline', '<', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter invisible="1" string="Late Activities" name="activities_overdue"
|
||||
domain="[('activity_ids.date_deadline', '<', context_today().strftime('%Y-%m-%d'))]"
|
||||
help="Show all opportunities for which the next action date is before today"/>
|
||||
|
||||
@@ -13,4 +13,4 @@ class AccountMove(models.Model):
|
||||
|
||||
@api.model
|
||||
def _l10n_in_get_shipping_partner_gstin(self, shipping_partner):
|
||||
return shipping_partner.l10n_in_shipping_gstin or shipping_partner.vat
|
||||
return shipping_partner.l10n_in_shipping_gstin
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from flectra import api, fields, models, _
|
||||
from flectra import api, fields, models, tools
|
||||
|
||||
|
||||
class MrpRoutingWorkcenter(models.Model):
|
||||
@@ -49,14 +49,24 @@ class MrpRoutingWorkcenter(models.Model):
|
||||
for operation in manual_ops:
|
||||
operation.time_cycle = operation.time_cycle_manual
|
||||
for operation in self - manual_ops:
|
||||
data = self.env['mrp.workorder'].read_group([
|
||||
data = self.env['mrp.workorder'].search([
|
||||
('operation_id', '=', operation.id),
|
||||
('qty_produced', '>', 0),
|
||||
('state', '=', 'done')], ['operation_id', 'duration', 'qty_produced'], ['operation_id'],
|
||||
limit=operation.time_mode_batch)
|
||||
count_data = dict((item['operation_id'][0], (item['duration'], item['qty_produced'])) for item in data)
|
||||
if count_data.get(operation.id) and count_data[operation.id][1]:
|
||||
operation.time_cycle = (count_data[operation.id][0] / count_data[operation.id][1]) * (operation.workcenter_id.capacity or 1.0)
|
||||
('state', '=', 'done')],
|
||||
limit=operation.time_mode_batch,
|
||||
order="date_finished desc")
|
||||
# To compute the time_cycle, we can take the total duration of previous operations
|
||||
# but for the quantity, we will take in consideration the qty_produced like if the capacity was 1.
|
||||
# So producing 50 in 00:10 with capacity 2, for the time_cycle, we assume it is 25 in 00:10
|
||||
# When recomputing the expected duration, the capacity is used again to divide the qty to produce
|
||||
# so that if we need 50 with capacity 2, it will compute the expected of 25 which is 00:10
|
||||
total_duration = 0 # Can be 0 since it's not an invalid duration for BoM
|
||||
cycle_number = 0 # Never 0 unless infinite item['workcenter_id'].capacity
|
||||
for item in data:
|
||||
total_duration += item['duration']
|
||||
cycle_number += tools.float_round((item['qty_produced'] / item['workcenter_id'].capacity or 1.0), precision_digits=0, rounding_method='UP')
|
||||
if cycle_number:
|
||||
operation.time_cycle = total_duration / cycle_number
|
||||
else:
|
||||
operation.time_cycle = operation.time_cycle_manual
|
||||
|
||||
|
||||
@@ -84,6 +84,20 @@ class TestMrpCommon(common2.TestStockCommon):
|
||||
'time_stop': 5,
|
||||
'time_efficiency': 80,
|
||||
})
|
||||
cls.workcenter_2 = cls.env['mrp.workcenter'].create({
|
||||
'name': 'Simple Workcenter',
|
||||
'capacity': 1,
|
||||
'time_start': 0,
|
||||
'time_stop': 0,
|
||||
'time_efficiency': 100,
|
||||
})
|
||||
cls.workcenter_3 = cls.env['mrp.workcenter'].create({
|
||||
'name': 'Double Workcenter',
|
||||
'capacity': 2,
|
||||
'time_start': 0,
|
||||
'time_stop': 0,
|
||||
'time_efficiency': 100,
|
||||
})
|
||||
|
||||
cls.bom_1 = cls.env['mrp.bom'].create({
|
||||
'product_id': cls.product_4.id,
|
||||
@@ -129,6 +143,45 @@ class TestMrpCommon(common2.TestStockCommon):
|
||||
(0, 0, {'product_id': cls.product_4.id, 'product_qty': 8}),
|
||||
(0, 0, {'product_id': cls.product_2.id, 'product_qty': 12})
|
||||
]})
|
||||
cls.bom_4 = cls.env['mrp.bom'].create({
|
||||
'product_id': cls.product_6.id,
|
||||
'product_tmpl_id': cls.product_6.product_tmpl_id.id,
|
||||
'consumption': 'flexible',
|
||||
'product_qty': 1.0,
|
||||
'operation_ids': [
|
||||
(0, 0, {'name': 'Rub it gently with a cloth', 'workcenter_id': cls.workcenter_2.id,
|
||||
'time_mode_batch': 1, 'time_mode': "auto", 'sequence': 1}),
|
||||
],
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [
|
||||
(0, 0, {'product_id': cls.product_1.id, 'product_qty': 1}),
|
||||
]})
|
||||
cls.bom_5 = cls.env['mrp.bom'].create({
|
||||
'product_id': cls.product_6.id,
|
||||
'product_tmpl_id': cls.product_6.product_tmpl_id.id,
|
||||
'consumption': 'flexible',
|
||||
'product_qty': 1.0,
|
||||
'operation_ids': [
|
||||
(0, 0, {'name': 'Rub it gently with a cloth two at once', 'workcenter_id': cls.workcenter_3.id,
|
||||
'time_mode_batch': 2, 'time_mode': "auto", 'sequence': 1}),
|
||||
],
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [
|
||||
(0, 0, {'product_id': cls.product_1.id, 'product_qty': 1}),
|
||||
]})
|
||||
cls.bom_6 = cls.env['mrp.bom'].create({
|
||||
'product_id': cls.product_6.id,
|
||||
'product_tmpl_id': cls.product_6.product_tmpl_id.id,
|
||||
'consumption': 'flexible',
|
||||
'product_qty': 1.0,
|
||||
'operation_ids': [
|
||||
(0, 0, {'name': 'Rub it gently with a cloth two at once', 'workcenter_id': cls.workcenter_3.id,
|
||||
'time_mode_batch': 1, 'time_mode': "auto", 'sequence': 1}),
|
||||
],
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [
|
||||
(0, 0, {'product_id': cls.product_1.id, 'product_qty': 1}),
|
||||
]})
|
||||
|
||||
cls.stock_location_14 = cls.env['stock.location'].create({
|
||||
'name': 'Shelf 2',
|
||||
|
||||
@@ -2053,3 +2053,134 @@ class TestMrpOrder(TestMrpCommon):
|
||||
mo4 = mo_form.save()
|
||||
self.assertEqual(len(mo4.move_finished_ids), 1, 'Wrong number of finish product moves created')
|
||||
self.assertEqual(mo4.move_finished_ids.product_id, product1, 'Wrong product to produce in finished product move')
|
||||
|
||||
def test_compute_tracked_time_1(self):
|
||||
"""
|
||||
Checks that the Duration Computation (`time_mode` of mrp.routing.workcenter) with value `auto` with Based On
|
||||
(`time_mode_batch`) set to 1 actually compute the time based on the last 1 operation, and not more.
|
||||
Create a first production in 15 minutes (expected should go from 60 to 15
|
||||
Create a second one in 10 minutes (expected should NOT go from 15 to 12.5, it should go from 15 to 10)
|
||||
"""
|
||||
# First production, the default is 60 and there is 0 productions of that operation
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.bom_id = self.bom_4
|
||||
production = production_form.save()
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 60.0, "Default duration is 0+0+1*60.0")
|
||||
production.action_confirm()
|
||||
production.button_plan()
|
||||
# Production planned, time to start, I produce all the 1 product
|
||||
production_form.qty_producing = 1
|
||||
with production_form.workorder_ids.edit(0) as wo:
|
||||
wo.duration = 15 # in 15 minutes
|
||||
production = production_form.save()
|
||||
production.button_mark_done()
|
||||
# It is saved and done, registered in the db. There are now 1 productions of that operation
|
||||
|
||||
# Same production, let's see what the duration_expected is, last prod was 15 minutes for 1 item
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.bom_id = self.bom_4
|
||||
production = production_form.save()
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 15.0, "Duration is now 0+0+1*15")
|
||||
production.action_confirm()
|
||||
production.button_plan()
|
||||
# Production planned, time to start, I produce all the 1 product
|
||||
production_form.qty_producing = 1
|
||||
with production_form.workorder_ids.edit(0) as wo:
|
||||
wo.duration = 10 # In 10 minutes this time
|
||||
production = production_form.save()
|
||||
production.button_mark_done()
|
||||
# It is saved and done, registered in the db. There are now 2 productions of that operation
|
||||
|
||||
# Same production, let's see what the duration_expected is, last prod was 10 minutes for 1 item
|
||||
# Total average time would be 12.5 but we compute the duration based on the last 1 item
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.bom_id = self.bom_4
|
||||
production = production_form.save()
|
||||
self.assertNotEqual(production.workorder_ids[0].duration_expected, 12.5, "Duration expected is based on the last 1 production, not last 2")
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 10.0, "Duration is now 0+0+1*10")
|
||||
|
||||
def test_compute_tracked_time_2_under_capacity(self):
|
||||
"""
|
||||
Test that when tracking the 2 last production, if we make one with under capacity, and one with normal capacity,
|
||||
the two are equivalent (1 done with capacity 2 in 10mn = 2 done with capacity 2 in 10mn)
|
||||
"""
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.bom_id = self.bom_5
|
||||
production = production_form.save()
|
||||
production.action_confirm()
|
||||
production.button_plan()
|
||||
|
||||
# Production planned, time to start, I produce all the 1 product
|
||||
production_form.qty_producing = 1
|
||||
with production_form.workorder_ids.edit(0) as wo:
|
||||
wo.duration = 10 # in 10 minutes
|
||||
production = production_form.save()
|
||||
production.button_mark_done()
|
||||
# It is saved and done, registered in the db. There are now 1 productions of that operation
|
||||
|
||||
# Same production, let's see what the duration_expected is, last prod was 10 minutes for 1 item
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.bom_id = self.bom_5
|
||||
production_form.product_qty = 2 # We want to produce 2 items (the capacity) now
|
||||
production = production_form.save()
|
||||
self.assertNotEqual(production.workorder_ids[0].duration_expected, 20.0, "We made 1 item with capacity 2 in 10mn -> so 2 items shouldn't be double that")
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 10.0, "Producing 1 or 2 items with capacity 2 is the same duration")
|
||||
production.action_confirm()
|
||||
production.button_plan()
|
||||
# Production planned, time to start, I produce all the 2 product
|
||||
production_form.qty_producing = 2
|
||||
with production_form.workorder_ids.edit(0) as wo:
|
||||
wo.duration = 10 # In 10 minutes this time
|
||||
production = production_form.save()
|
||||
production.button_mark_done()
|
||||
# It is saved and done, registered in the db. There are now 2 productions of that operation but they have the same duration
|
||||
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.bom_id = self.bom_5
|
||||
production = production_form.save()
|
||||
self.assertNotEqual(production.workorder_ids[0].duration_expected, 15, "Producing 1 or 2 in 10mn with capacity 2 take the same amount of time : 10mn")
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 10.0, "Duration is indeed (10+10)/2")
|
||||
|
||||
def test_capacity_duration_expected(self):
|
||||
"""
|
||||
Test that the duration expected is correctly computed when dealing with below or above capacity
|
||||
1 -> 10mn
|
||||
2 -> 10mn
|
||||
3 -> 20mn
|
||||
4 -> 20mn
|
||||
5 -> 30mn
|
||||
...
|
||||
"""
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.bom_id = self.bom_6
|
||||
production = production_form.save()
|
||||
production.action_confirm()
|
||||
production.button_plan()
|
||||
|
||||
# Production planned, time to start, I produce all the 1 product
|
||||
production_form.qty_producing = 1
|
||||
with production_form.workorder_ids.edit(0) as wo:
|
||||
wo.duration = 10 # in 10 minutes
|
||||
production = production_form.save()
|
||||
production.button_mark_done()
|
||||
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.bom_id = self.bom_6
|
||||
production = production_form.save()
|
||||
# production_form.product_qty = 1 [BY DEFAULT]
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 10.0, "Produce 1 with capacity 2, expected is 10mn for each run -> 10mn")
|
||||
production_form.product_qty = 2
|
||||
production = production_form.save()
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 10.0, "Produce 2 with capacity 2, expected is 10mn for each run -> 10mn")
|
||||
|
||||
production_form.product_qty = 3
|
||||
production = production_form.save()
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 20.0, "Produce 3 with capacity 2, expected is 10mn for each run -> 20mn")
|
||||
|
||||
production_form.product_qty = 4
|
||||
production = production_form.save()
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 20.0, "Produce 4 with capacity 2, expected is 10mn for each run -> 20mn")
|
||||
|
||||
production_form.product_qty = 5
|
||||
production = production_form.save()
|
||||
self.assertEqual(production.workorder_ids[0].duration_expected, 30.0, "Produce 5 with capacity 2, expected is 10mn for each run -> 30mn")
|
||||
|
||||
@@ -323,7 +323,7 @@ flectra.define('point_of_sale.PaymentScreen', function (require) {
|
||||
const isPaymentSuccessful = await payment_terminal.send_payment_request(line.cid);
|
||||
if (isPaymentSuccessful) {
|
||||
line.set_payment_status('done');
|
||||
line.can_be_reversed = this.payment_interface.supports_reversals;
|
||||
line.can_be_reversed = payment_terminal.supports_reversals;
|
||||
} else {
|
||||
line.set_payment_status('retry');
|
||||
}
|
||||
|
||||
@@ -650,7 +650,7 @@
|
||||
<div class="oe_title pr-0">
|
||||
<h1 class="d-flex flex-row justify-content-between">
|
||||
<field name="priority" widget="priority" class="mr-3"/>
|
||||
<field name="name" class="o_task_name text-truncate" placeholder="Task Title..."/>
|
||||
<field name="name" class="o_task_name text-truncate" placeholder="Task Title..." default_focus="1" />
|
||||
<field name="kanban_state" widget="state_selection" class="ml-auto"/>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
@@ -272,7 +272,7 @@ class PurchaseOrderLine(models.Model):
|
||||
qty_received_method = fields.Selection(selection_add=[('stock_moves', 'Stock Moves')])
|
||||
|
||||
move_ids = fields.One2many('stock.move', 'purchase_line_id', string='Reservation', readonly=True, copy=False)
|
||||
orderpoint_id = fields.Many2one('stock.warehouse.orderpoint', 'Orderpoint')
|
||||
orderpoint_id = fields.Many2one('stock.warehouse.orderpoint', 'Orderpoint', copy=False)
|
||||
move_dest_ids = fields.One2many('stock.move', 'created_purchase_line_id', 'Downstream Moves')
|
||||
product_description_variants = fields.Char('Custom Description')
|
||||
propagate_cancel = fields.Boolean('Propagate cancellation', default=True)
|
||||
@@ -442,8 +442,15 @@ class PurchaseOrderLine(models.Model):
|
||||
res.append(extra_move_vals)
|
||||
return res
|
||||
|
||||
def _check_orderpoint_picking_type(self):
|
||||
warehouse_loc = self.order_id.picking_type_id.warehouse_id.view_location_id
|
||||
if self.orderpoint_id and not warehouse_loc.parent_path in self.orderpoint_id.location_id.parent_path:
|
||||
raise UserError(_('For the product %s, the warehouse of the operation type (%s) is inconsistent with the location (%s) of the reordering rule (%s). Change the operation type or cancel the request for quotation.',
|
||||
self.product_id.display_name, self.order_id.picking_type_id.display_name, self.orderpoint_id.location_id.display_name, self.orderpoint_id.display_name))
|
||||
|
||||
def _prepare_stock_move_vals(self, picking, price_unit, product_uom_qty, product_uom):
|
||||
self.ensure_one()
|
||||
self._check_orderpoint_picking_type()
|
||||
product = self.product_id.with_context(lang=self.order_id.dest_address_id.lang or self.env.user.lang)
|
||||
description_picking = product._get_description(self.order_id.picking_type_id)
|
||||
if self.product_description_variants:
|
||||
|
||||
@@ -7,6 +7,7 @@ from datetime import timedelta as td
|
||||
from flectra import SUPERUSER_ID
|
||||
from flectra.tests import Form
|
||||
from flectra.tests.common import SavepointCase
|
||||
from flectra.exceptions import UserError
|
||||
|
||||
|
||||
class TestReorderingRule(SavepointCase):
|
||||
@@ -38,7 +39,8 @@ class TestReorderingRule(SavepointCase):
|
||||
"""
|
||||
warehouse_1 = self.env['stock.warehouse'].search([('company_id', '=', self.env.user.id)], limit=1)
|
||||
warehouse_1.write({'reception_steps': 'two_steps'})
|
||||
|
||||
warehouse_2 = self.env['stock.warehouse'].create({'name': 'WH 2', 'code': 'WH2', 'company_id': self.env.company.id, 'partner_id': self.env.company.partner_id.id, 'reception_steps': 'one_step'})
|
||||
|
||||
# create reordering rule
|
||||
orderpoint_form = Form(self.env['stock.warehouse.orderpoint'])
|
||||
orderpoint_form.warehouse_id = warehouse_1
|
||||
@@ -63,6 +65,12 @@ class TestReorderingRule(SavepointCase):
|
||||
# Check purchase order created or not
|
||||
purchase_order = self.env['purchase.order'].search([('partner_id', '=', self.partner.id)])
|
||||
self.assertTrue(purchase_order, 'No purchase order created.')
|
||||
|
||||
# Check the picking type on the purchase order
|
||||
purchase_order.picking_type_id = warehouse_2.in_type_id
|
||||
with self.assertRaises(UserError):
|
||||
purchase_order.button_confirm()
|
||||
purchase_order.picking_type_id = warehouse_1.in_type_id
|
||||
|
||||
# On the po generated, the source document should be the name of the reordering rule
|
||||
self.assertEqual(order_point.name, purchase_order.origin, 'Source document on purchase order should be the name of the reordering rule.')
|
||||
|
||||
@@ -63,7 +63,7 @@ class Location(models.Model):
|
||||
|
||||
_sql_constraints = [('barcode_company_uniq', 'unique (barcode,company_id)', 'The barcode for a location must be unique per company !')]
|
||||
|
||||
@api.depends('name', 'location_id.complete_name')
|
||||
@api.depends('name', 'location_id.complete_name', 'usage')
|
||||
def _compute_complete_name(self):
|
||||
for location in self:
|
||||
if location.location_id and location.usage != 'view':
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<h6 class="o_wevent_sidebar_title">
|
||||
<t t-if="country">
|
||||
<i class="fa fa-flag mr-2"/>Events: <span t-esc="country.name"/>
|
||||
<img class="img-fluid" t-att-src="website.image_url(country, 'image')" alt=""/>
|
||||
<img class="img-fluid" t-att-src="country.image_url" alt=""/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<i class="fa fa-globe mr-2"/>Upcoming Events
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<xpath expr="//field[@name='slide_type']" position="after">
|
||||
<field name="survey_id"
|
||||
attrs="{'invisible': [('slide_type', '!=', 'certification')], 'required': [('slide_type', '=', 'certification')]}"
|
||||
domain="[('certification', '=', True)]"/>
|
||||
domain="[('certification', '=', True)]" context="{'default_certification': True, 'default_scoring_type': 'scoring_without_answers'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
Reference in New Issue
Block a user