[MERGE] forward port branch saas-11 up to 58f68cc
This commit is contained in:
@@ -70,6 +70,13 @@ class AccountMove(models.Model):
|
|||||||
if self.env.context.get('default_journal_type'):
|
if self.env.context.get('default_journal_type'):
|
||||||
return self.env['account.journal'].search([('type', '=', self.env.context['default_journal_type'])], limit=1).id
|
return self.env['account.journal'].search([('type', '=', self.env.context['default_journal_type'])], limit=1).id
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
@api.depends('line_ids.partner_id')
|
||||||
|
def _compute_partner_id(self):
|
||||||
|
for move in self:
|
||||||
|
partner = move.line_ids.mapped('partner_id')
|
||||||
|
move.partner_id = partner.id if len(partner) == 1 else False
|
||||||
|
|
||||||
name = fields.Char(string='Number', required=True, copy=False, default='/')
|
name = fields.Char(string='Number', required=True, copy=False, default='/')
|
||||||
ref = fields.Char(string='Reference', copy=False)
|
ref = fields.Char(string='Reference', copy=False)
|
||||||
date = fields.Date(required=True, states={'posted': [('readonly', True)]}, index=True, default=fields.Date.context_today)
|
date = fields.Date(required=True, states={'posted': [('readonly', True)]}, index=True, default=fields.Date.context_today)
|
||||||
@@ -84,7 +91,7 @@ class AccountMove(models.Model):
|
|||||||
'in \'Posted\' status.')
|
'in \'Posted\' status.')
|
||||||
line_ids = fields.One2many('account.move.line', 'move_id', string='Journal Items',
|
line_ids = fields.One2many('account.move.line', 'move_id', string='Journal Items',
|
||||||
states={'posted': [('readonly', True)]}, copy=True)
|
states={'posted': [('readonly', True)]}, copy=True)
|
||||||
partner_id = fields.Many2one('res.partner', related='line_ids.partner_id', string="Partner", store=True, readonly=True)
|
partner_id = fields.Many2one('res.partner', compute='_compute_partner_id', string="Partner", store=True, readonly=True)
|
||||||
amount = fields.Monetary(compute='_amount_compute', store=True)
|
amount = fields.Monetary(compute='_amount_compute', store=True)
|
||||||
narration = fields.Text(string='Internal Note')
|
narration = fields.Text(string='Internal Note')
|
||||||
company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', store=True, readonly=True,
|
company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', store=True, readonly=True,
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class AccountInvoiceLine(models.Model):
|
|||||||
'partner_id': self.invoice_id.partner_id.id,
|
'partner_id': self.invoice_id.partner_id.id,
|
||||||
'company_id': self.invoice_id.company_id.id,
|
'company_id': self.invoice_id.company_id.id,
|
||||||
'currency_id': self.invoice_id.company_currency_id.id,
|
'currency_id': self.invoice_id.company_currency_id.id,
|
||||||
'date': self.asset_start_date or self.invoice_id.date_invoice,
|
'date': self.invoice_id.date_invoice,
|
||||||
'invoice_id': self.invoice_id.id,
|
'invoice_id': self.invoice_id.id,
|
||||||
}
|
}
|
||||||
changed_vals = self.env['account.asset.asset'].onchange_category_id_values(vals['category_id'])
|
changed_vals = self.env['account.asset.asset'].onchange_category_id_values(vals['category_id'])
|
||||||
|
|||||||
@@ -24,18 +24,18 @@
|
|||||||
<group string="Journal Entries">
|
<group string="Journal Entries">
|
||||||
<field name="journal_id"/>
|
<field name="journal_id"/>
|
||||||
<div>
|
<div>
|
||||||
<label for="account_asset_id" string="Depreciation Asset Account" attrs="{'invisible': [('type','!=','purchase')]}"/>
|
<label for="account_asset_id" attrs="{'invisible': [('type','!=','purchase')]}"/>
|
||||||
<label for="account_asset_id" string="Deferred Revenue Account" attrs="{'invisible': [('type','!=','sale')]}"/>
|
<label for="account_asset_id" string="Deferred Revenue Account" attrs="{'invisible': [('type','!=','sale')]}"/>
|
||||||
</div>
|
</div>
|
||||||
<field name="account_asset_id" nolabel="1" attrs="{'invisible': [('type','=', False)]}"/>
|
<field name="account_asset_id" nolabel="1" attrs="{'invisible': [('type','=', False)]}"/>
|
||||||
<div>
|
<div>
|
||||||
<label for="account_depreciation_id" string="Depreciation Entries: Asset Account" attrs="{'invisible': [('type','!=','purchase')]}"/>
|
<label for="account_depreciation_id" attrs="{'invisible': [('type','!=','purchase')]}"/>
|
||||||
<label for="account_depreciation_id" string="Recognition Account" attrs="{'invisible': [('type','!=','sale')]}"/>
|
<label for="account_depreciation_id" string="Recognition Income Account" attrs="{'invisible': [('type','!=','sale')]}"/>
|
||||||
</div>
|
</div>
|
||||||
<field name="account_depreciation_id" nolabel="1"/>
|
<field name="account_depreciation_id" nolabel="1"/>
|
||||||
<div>
|
<div>
|
||||||
<label for="account_depreciation_expense_id" string="Depreciation Expense Account" attrs="{'invisible': [('type','!=','purchase')]}"/>
|
<label for="account_depreciation_expense_id" attrs="{'invisible': [('type','!=','purchase')]}"/>
|
||||||
<label for="account_depreciation_expense_id" string="Recognition Income Account" attrs="{'invisible': [('type','!=','sale')]}"/>
|
<label for="account_depreciation_expense_id" string="Recognition Account" attrs="{'invisible': [('type','!=','sale')]}"/>
|
||||||
</div>
|
</div>
|
||||||
<field name="account_depreciation_expense_id" nolabel="1"/>
|
<field name="account_depreciation_expense_id" nolabel="1"/>
|
||||||
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
|
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
|
||||||
|
|||||||
@@ -213,7 +213,11 @@ class AccountBankStatementImport(models.TransientModel):
|
|||||||
if 'unique_import_id' not in line_vals \
|
if 'unique_import_id' not in line_vals \
|
||||||
or not line_vals['unique_import_id'] \
|
or not line_vals['unique_import_id'] \
|
||||||
or not bool(BankStatementLine.sudo().search([('unique_import_id', '=', line_vals['unique_import_id'])], limit=1)):
|
or not bool(BankStatementLine.sudo().search([('unique_import_id', '=', line_vals['unique_import_id'])], limit=1)):
|
||||||
filtered_st_lines.append(line_vals)
|
if line_vals['amount'] != 0:
|
||||||
|
# Some banks, like ING, create a line for free charges.
|
||||||
|
# We just skip those lines as there's a 'non-zero' constraint
|
||||||
|
# on the amount of account.bank.statement.line
|
||||||
|
filtered_st_lines.append(line_vals)
|
||||||
else:
|
else:
|
||||||
ignored_statement_lines_import_ids.append(line_vals['unique_import_id'])
|
ignored_statement_lines_import_ids.append(line_vals['unique_import_id'])
|
||||||
if len(filtered_st_lines) > 0:
|
if len(filtered_st_lines) > 0:
|
||||||
|
|||||||
@@ -94,7 +94,11 @@ class StockPicking(models.Model):
|
|||||||
@api.onchange('carrier_id')
|
@api.onchange('carrier_id')
|
||||||
def onchange_carrier(self):
|
def onchange_carrier(self):
|
||||||
if self.carrier_id.delivery_type in ['fixed', 'base_on_rule']:
|
if self.carrier_id.delivery_type in ['fixed', 'base_on_rule']:
|
||||||
self.carrier_price = self.carrier_id.price
|
order = self.sale_id
|
||||||
|
if order:
|
||||||
|
self.carrier_price = self.carrier_id.get_price_available(order)
|
||||||
|
else:
|
||||||
|
self.carrier_price = self.carrier_id.price
|
||||||
|
|
||||||
@api.depends('product_id', 'move_lines')
|
@api.depends('product_id', 'move_lines')
|
||||||
def _cal_weight(self):
|
def _cal_weight(self):
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class AccountAnalyticLine(models.Model):
|
|||||||
|
|
||||||
task_id = fields.Many2one('project.task', 'Task')
|
task_id = fields.Many2one('project.task', 'Task')
|
||||||
project_id = fields.Many2one('project.project', 'Project')
|
project_id = fields.Many2one('project.project', 'Project')
|
||||||
department_id = fields.Many2one('hr.department', "Department", related='user_id.employee_ids.department_id', store=True)
|
department_id = fields.Many2one('hr.department', "Department", related='user_id.employee_ids.department_id', store=True, readonly=True)
|
||||||
|
|
||||||
@api.onchange('project_id')
|
@api.onchange('project_id')
|
||||||
def onchange_project_id(self):
|
def onchange_project_id(self):
|
||||||
|
|||||||
@@ -32,3 +32,5 @@ access_barcode_nomenclature_pos_user,barcode.nomenclature.pos.user,barcodes.mode
|
|||||||
access_barcode_nomenclature_pos_manager,barcode.nomenclature.pos.manager,barcodes.model_barcode_nomenclature,group_pos_manager,1,1,1,1
|
access_barcode_nomenclature_pos_manager,barcode.nomenclature.pos.manager,barcodes.model_barcode_nomenclature,group_pos_manager,1,1,1,1
|
||||||
access_barcode_rule_pos_user,barcode.rule.pos.user,barcodes.model_barcode_rule,group_pos_user,1,0,0,0
|
access_barcode_rule_pos_user,barcode.rule.pos.user,barcodes.model_barcode_rule,group_pos_user,1,0,0,0
|
||||||
access_barcode_rule_pos_manager,barcode.rule.pos.manager,barcodes.model_barcode_rule,group_pos_manager,1,1,1,1
|
access_barcode_rule_pos_manager,barcode.rule.pos.manager,barcodes.model_barcode_rule,group_pos_manager,1,1,1,1
|
||||||
|
access_bank_statement_cashbox_user,account.bank.statement.cashbox user,account.model_account_bank_statement_cashbox,group_pos_user,1,1,1,0
|
||||||
|
access_account_cashbox_line_user,account.cashbox.line user,account.model_account_cashbox_line,group_pos_user,1,1,1,0
|
||||||
|
|||||||
|
@@ -72,5 +72,6 @@ class SaleOrderLine(models.Model):
|
|||||||
@api.multi
|
@api.multi
|
||||||
def _get_display_price(self, product):
|
def _get_display_price(self, product):
|
||||||
if self.order_id.pricelist_id.discount_policy == 'without_discount':
|
if self.order_id.pricelist_id.discount_policy == 'without_discount':
|
||||||
return product.lst_price
|
return self.order_id.company_id.currency_id.compute(
|
||||||
|
product.lst_price, self.order_id.pricelist_id.currency_id)
|
||||||
return super(SaleOrderLine, self)._get_display_price(product)
|
return super(SaleOrderLine, self)._get_display_price(product)
|
||||||
|
|||||||
@@ -750,8 +750,8 @@ class StockMove(models.Model):
|
|||||||
owner_id=pack_operation.owner_id.id, src_package_id=pack_operation.package_id.id,
|
owner_id=pack_operation.owner_id.id, src_package_id=pack_operation.package_id.id,
|
||||||
dest_package_id=dest_package_id)
|
dest_package_id=dest_package_id)
|
||||||
if redo_false_quants:
|
if redo_false_quants:
|
||||||
false_quants_move = [x for x in move_rec_updateme.reserved_quant_ids if (not x.lot_id) and (x.owner_id.id == pack_operation.owner_id.id) \
|
false_quants_move = [x for x in move_rec_updateme.reserved_quant_ids if (not x.lot_id) and (x.owner_id.id == pack_operation.owner_id.id) and
|
||||||
and (x.location_id.id == pack_operation.location_id.id) and (x.package_id.id != pack_operation.package_id.id)]
|
(x.location_id.id == pack_operation.location_id.id) and (x.package_id.id == pack_operation.package_id.id)]
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
|
|||||||
@@ -27,15 +27,16 @@ class TestStockCommon(common.TransactionCase):
|
|||||||
self.picking_type_out = self.ModelDataObj.xmlid_to_res_id('stock.picking_type_out')
|
self.picking_type_out = self.ModelDataObj.xmlid_to_res_id('stock.picking_type_out')
|
||||||
self.supplier_location = self.ModelDataObj.xmlid_to_res_id('stock.stock_location_suppliers')
|
self.supplier_location = self.ModelDataObj.xmlid_to_res_id('stock.stock_location_suppliers')
|
||||||
self.stock_location = self.ModelDataObj.xmlid_to_res_id('stock.stock_location_stock')
|
self.stock_location = self.ModelDataObj.xmlid_to_res_id('stock.stock_location_stock')
|
||||||
|
self.pack_location = self.ModelDataObj.xmlid_to_res_id('stock.location_pack_zone')
|
||||||
self.customer_location = self.ModelDataObj.xmlid_to_res_id('stock.stock_location_customers')
|
self.customer_location = self.ModelDataObj.xmlid_to_res_id('stock.stock_location_customers')
|
||||||
self.categ_unit = self.ModelDataObj.xmlid_to_res_id('product.product_uom_categ_unit')
|
self.categ_unit = self.ModelDataObj.xmlid_to_res_id('product.product_uom_categ_unit')
|
||||||
self.categ_kgm = self.ModelDataObj.xmlid_to_res_id('product.product_uom_categ_kgm')
|
self.categ_kgm = self.ModelDataObj.xmlid_to_res_id('product.product_uom_categ_kgm')
|
||||||
|
|
||||||
# Product Created A, B, C, D
|
# Product Created A, B, C, D
|
||||||
self.productA = self.ProductObj.create({'name': 'Product A'})
|
self.productA = self.ProductObj.create({'name': 'Product A', 'type': 'product'})
|
||||||
self.productB = self.ProductObj.create({'name': 'Product B'})
|
self.productB = self.ProductObj.create({'name': 'Product B', 'type': 'product'})
|
||||||
self.productC = self.ProductObj.create({'name': 'Product C'})
|
self.productC = self.ProductObj.create({'name': 'Product C', 'type': 'product'})
|
||||||
self.productD = self.ProductObj.create({'name': 'Product D'})
|
self.productD = self.ProductObj.create({'name': 'Product D', 'type': 'product'})
|
||||||
|
|
||||||
# Configure unit of measure.
|
# Configure unit of measure.
|
||||||
self.uom_kg = self.UomObj.create({
|
self.uom_kg = self.UomObj.create({
|
||||||
@@ -90,9 +91,9 @@ class TestStockCommon(common.TransactionCase):
|
|||||||
'rounding': 1.0})
|
'rounding': 1.0})
|
||||||
|
|
||||||
# Product for different unit of measure.
|
# Product for different unit of measure.
|
||||||
self.DozA = self.ProductObj.create({'name': 'Dozon-A', 'uom_id': self.uom_dozen.id, 'uom_po_id': self.uom_dozen.id})
|
self.DozA = self.ProductObj.create({'name': 'Dozon-A', 'type': 'product', 'uom_id': self.uom_dozen.id, 'uom_po_id': self.uom_dozen.id})
|
||||||
self.SDozA = self.ProductObj.create({'name': 'SuperDozon-A', 'uom_id': self.uom_sdozen.id, 'uom_po_id': self.uom_sdozen.id})
|
self.SDozA = self.ProductObj.create({'name': 'SuperDozon-A', 'type': 'product', 'uom_id': self.uom_sdozen.id, 'uom_po_id': self.uom_sdozen.id})
|
||||||
self.SDozARound = self.ProductObj.create({'name': 'SuperDozenRound-A', 'uom_id': self.uom_sdozen_round.id, 'uom_po_id': self.uom_sdozen_round.id})
|
self.SDozARound = self.ProductObj.create({'name': 'SuperDozenRound-A', 'type': 'product', 'uom_id': self.uom_sdozen_round.id, 'uom_po_id': self.uom_sdozen_round.id})
|
||||||
self.UnitA = self.ProductObj.create({'name': 'Unit-A'})
|
self.UnitA = self.ProductObj.create({'name': 'Unit-A', 'type': 'product'})
|
||||||
self.kgB = self.ProductObj.create({'name': 'kg-B', 'uom_id': self.uom_kg.id, 'uom_po_id': self.uom_kg.id})
|
self.kgB = self.ProductObj.create({'name': 'kg-B', 'type': 'product', 'uom_id': self.uom_kg.id, 'uom_po_id': self.uom_kg.id})
|
||||||
self.gB = self.ProductObj.create({'name': 'g-B', 'uom_id': self.uom_gm.id, 'uom_po_id': self.uom_gm.id})
|
self.gB = self.ProductObj.create({'name': 'g-B', 'type': 'product', 'uom_id': self.uom_gm.id, 'uom_po_id': self.uom_gm.id})
|
||||||
|
|||||||
@@ -205,19 +205,21 @@ class TestStockFlow(TestStockCommon):
|
|||||||
self.assertEqual(move.state, 'confirmed', 'Wrong state of move line.')
|
self.assertEqual(move.state, 'confirmed', 'Wrong state of move line.')
|
||||||
# Product assign to outgoing shipments
|
# Product assign to outgoing shipments
|
||||||
picking_out.action_assign()
|
picking_out.action_assign()
|
||||||
for move in picking_out.move_lines:
|
self.assertEqual(picking_out.move_lines[0].state, 'confirmed', 'Wrong state of move line.')
|
||||||
self.assertEqual(move.state, 'assigned', 'Wrong state of move line.')
|
self.assertEqual(picking_out.move_lines[1].state, 'assigned', 'Wrong state of move line.')
|
||||||
|
self.assertEqual(picking_out.move_lines[2].state, 'assigned', 'Wrong state of move line.')
|
||||||
|
self.assertEqual(picking_out.move_lines[3].state, 'confirmed', 'Wrong state of move line.')
|
||||||
# Check availability for product A
|
# Check availability for product A
|
||||||
aval_a_qty = self.MoveObj.search([('product_id', '=', self.productA.id), ('picking_id', '=', picking_out.id)], limit=1).availability
|
aval_a_qty = self.MoveObj.search([('product_id', '=', self.productA.id), ('picking_id', '=', picking_out.id)], limit=1).reserved_availability
|
||||||
self.assertEqual(aval_a_qty, 4.0, 'Wrong move quantity availability of product A (%s found instead of 4)' % (aval_a_qty))
|
self.assertEqual(aval_a_qty, 4.0, 'Wrong move quantity availability of product A (%s found instead of 4)' % (aval_a_qty))
|
||||||
# Check availability for product B
|
# Check availability for product B
|
||||||
aval_b_qty = self.MoveObj.search([('product_id', '=', self.productB.id), ('picking_id', '=', picking_out.id)], limit=1).availability
|
aval_b_qty = self.MoveObj.search([('product_id', '=', self.productB.id), ('picking_id', '=', picking_out.id)], limit=1).reserved_availability
|
||||||
self.assertEqual(aval_b_qty, 5.0, 'Wrong move quantity availability of product B (%s found instead of 5)' % (aval_b_qty))
|
self.assertEqual(aval_b_qty, 5.0, 'Wrong move quantity availability of product B (%s found instead of 5)' % (aval_b_qty))
|
||||||
# Check availability for product C
|
# Check availability for product C
|
||||||
aval_c_qty = self.MoveObj.search([('product_id', '=', self.productC.id), ('picking_id', '=', picking_out.id)], limit=1).availability
|
aval_c_qty = self.MoveObj.search([('product_id', '=', self.productC.id), ('picking_id', '=', picking_out.id)], limit=1).reserved_availability
|
||||||
self.assertEqual(aval_c_qty, 3.0, 'Wrong move quantity availability of product C (%s found instead of 3)' % (aval_c_qty))
|
self.assertEqual(aval_c_qty, 3.0, 'Wrong move quantity availability of product C (%s found instead of 3)' % (aval_c_qty))
|
||||||
# Check availability for product D
|
# Check availability for product D
|
||||||
aval_d_qty = self.MoveObj.search([('product_id', '=', self.productD.id), ('picking_id', '=', picking_out.id)], limit=1).availability
|
aval_d_qty = self.MoveObj.search([('product_id', '=', self.productD.id), ('picking_id', '=', picking_out.id)], limit=1).reserved_availability
|
||||||
self.assertEqual(aval_d_qty, 7.0, 'Wrong move quantity availability of product D (%s found instead of 7)' % (aval_d_qty))
|
self.assertEqual(aval_d_qty, 7.0, 'Wrong move quantity availability of product D (%s found instead of 7)' % (aval_d_qty))
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
@@ -815,23 +817,21 @@ class TestStockFlow(TestStockCommon):
|
|||||||
for move in picking_out.move_lines:
|
for move in picking_out.move_lines:
|
||||||
self.assertEqual(move.state, 'assigned', 'Wrong state of move line.')
|
self.assertEqual(move.state, 'assigned', 'Wrong state of move line.')
|
||||||
# Check product A available quantity
|
# Check product A available quantity
|
||||||
DozA_qty = self.MoveObj.search([('product_id', '=', self.DozA.id), ('picking_id', '=', picking_out.id)], limit=1).availability
|
DozA_qty = self.MoveObj.search([('product_id', '=', self.DozA.id), ('picking_id', '=', picking_out.id)], limit=1).reserved_availability
|
||||||
self.assertEqual(DozA_qty, 4.5, 'Wrong move quantity availability (%s found instead of 4.5)' % (DozA_qty))
|
self.assertEqual(DozA_qty, 4.5, 'Wrong move quantity availability (%s found instead of 4.5)' % (DozA_qty))
|
||||||
# Check product B available quantity
|
# Check product B available quantity
|
||||||
SDozA_qty = self.MoveObj.search([('product_id', '=', self.SDozA.id), ('picking_id', '=', picking_out.id)], limit=1).availability
|
SDozA_qty = self.MoveObj.search([('product_id', '=', self.SDozA.id), ('picking_id', '=', picking_out.id)], limit=1).reserved_availability
|
||||||
self.assertEqual(SDozA_qty, 2, 'Wrong move quantity availability (%s found instead of 2)' % (SDozA_qty))
|
self.assertEqual(SDozA_qty, 2, 'Wrong move quantity availability (%s found instead of 2)' % (SDozA_qty))
|
||||||
# Check product C available quantity
|
# Check product C available quantity
|
||||||
SDozARound_qty = self.MoveObj.search([('product_id', '=', self.SDozARound.id), ('picking_id', '=', picking_out.id)], limit=1).availability
|
SDozARound_qty = self.MoveObj.search([('product_id', '=', self.SDozARound.id), ('picking_id', '=', picking_out.id)], limit=1).reserved_availability
|
||||||
self.assertEqual(SDozARound_qty, 3, 'Wrong move quantity availability (%s found instead of 3)' % (SDozARound_qty))
|
self.assertEqual(SDozARound_qty, 3, 'Wrong move quantity availability (%s found instead of 3)' % (SDozARound_qty))
|
||||||
# Check product D available quantity
|
# Check product D available quantity
|
||||||
gB_qty = self.MoveObj.search([('product_id', '=', self.gB.id), ('picking_id', '=', picking_out.id)], limit=1).availability
|
gB_qty = self.MoveObj.search([('product_id', '=', self.gB.id), ('picking_id', '=', picking_out.id)], limit=1).reserved_availability
|
||||||
self.assertEqual(gB_qty, 503, 'Wrong move quantity availability (%s found instead of 503)' % (gB_qty))
|
self.assertEqual(gB_qty, 503, 'Wrong move quantity availability (%s found instead of 503)' % (gB_qty))
|
||||||
# Check product D available quantity
|
# Check product D available quantity
|
||||||
kgB_qty = self.MoveObj.search([('product_id', '=', self.kgB.id), ('picking_id', '=', picking_out.id)], limit=1).availability
|
kgB_qty = self.MoveObj.search([('product_id', '=', self.kgB.id), ('picking_id', '=', picking_out.id)], limit=1).reserved_availability
|
||||||
self.assertEqual(kgB_qty, 0.020, 'Wrong move quantity availability (%s found instead of 0.020)' % (kgB_qty))
|
self.assertEqual(kgB_qty, 0.020, 'Wrong move quantity availability (%s found instead of 0.020)' % (kgB_qty))
|
||||||
|
|
||||||
picking_out.action_confirm()
|
|
||||||
picking_out.action_assign()
|
|
||||||
picking_out.do_prepare_partial()
|
picking_out.do_prepare_partial()
|
||||||
picking_out.do_transfer()
|
picking_out.do_transfer()
|
||||||
|
|
||||||
@@ -1276,4 +1276,137 @@ class TestStockFlow(TestStockCommon):
|
|||||||
self.assertEqual(sum([x.qty for x in quants if not x.lot_id]), 0.0, 'Wrong sum of quants with no lot')
|
self.assertEqual(sum([x.qty for x in quants if not x.lot_id]), 0.0, 'Wrong sum of quants with no lot')
|
||||||
self.assertEqual(sum([x.qty for x in quants if x.lot_id.id == lot1.id]), 1.0, 'Wrong sum of quants with lot 1')
|
self.assertEqual(sum([x.qty for x in quants if x.lot_id.id == lot1.id]), 1.0, 'Wrong sum of quants with lot 1')
|
||||||
self.assertEqual(sum([x.qty for x in quants if x.lot_id.id == lot2.id]), 1.0, 'Wrong sum of quants with lot 2')
|
self.assertEqual(sum([x.qty for x in quants if x.lot_id.id == lot2.id]), 1.0, 'Wrong sum of quants with lot 2')
|
||||||
self.assertEqual(sum([x.qty for x in quants if x.lot_id.id == lot3.id]), 2.0, 'Wrong sum of quants with lot 3')
|
self.assertEqual(sum([x.qty for x in quants if x.lot_id.id == lot3.id]), 2.0, 'Wrong sum of quants with lot 3')
|
||||||
|
|
||||||
|
|
||||||
|
def test_40_pack_in_pack(self):
|
||||||
|
""" Put a pack in pack"""
|
||||||
|
picking_out = self.PickingObj.create({
|
||||||
|
'partner_id': self.partner_agrolite_id,
|
||||||
|
'picking_type_id': self.picking_type_out,
|
||||||
|
'location_id': self.pack_location,
|
||||||
|
'location_dest_id': self.customer_location})
|
||||||
|
move_out = self.MoveObj.create({
|
||||||
|
'name': self.productA.name,
|
||||||
|
'product_id': self.productA.id,
|
||||||
|
'product_uom_qty': 3,
|
||||||
|
'product_uom': self.productA.uom_id.id,
|
||||||
|
'picking_id': picking_out.id,
|
||||||
|
'location_id': self.pack_location,
|
||||||
|
'location_dest_id': self.customer_location})
|
||||||
|
picking_pack = self.PickingObj.create({
|
||||||
|
'partner_id': self.partner_agrolite_id,
|
||||||
|
'picking_type_id': self.picking_type_out,
|
||||||
|
'location_id': self.stock_location ,
|
||||||
|
'location_dest_id': self.pack_location})
|
||||||
|
move_pack = self.MoveObj.create({
|
||||||
|
'name': self.productA.name,
|
||||||
|
'product_id': self.productA.id,
|
||||||
|
'product_uom_qty': 3,
|
||||||
|
'product_uom': self.productA.uom_id.id,
|
||||||
|
'picking_id': picking_pack.id,
|
||||||
|
'location_id': self.stock_location,
|
||||||
|
'location_dest_id': self.pack_location,
|
||||||
|
'move_dest_id': move_out.id})
|
||||||
|
picking_in = self.PickingObj.create({
|
||||||
|
'partner_id': self.partner_delta_id,
|
||||||
|
'picking_type_id': self.picking_type_in,
|
||||||
|
'location_id': self.supplier_location,
|
||||||
|
'location_dest_id': self.stock_location})
|
||||||
|
move_in = self.MoveObj.create({
|
||||||
|
'name': self.productA.name,
|
||||||
|
'product_id': self.productA.id,
|
||||||
|
'product_uom_qty': 3,
|
||||||
|
'product_uom': self.productA.uom_id.id,
|
||||||
|
'picking_id': picking_in.id,
|
||||||
|
'location_id': self.supplier_location,
|
||||||
|
'location_dest_id': self.stock_location,
|
||||||
|
'move_dest_id': move_pack.id})
|
||||||
|
|
||||||
|
# Check incoming shipment move lines state.
|
||||||
|
for move in picking_in.move_lines:
|
||||||
|
self.assertEqual(move.state, 'draft', 'Wrong state of move line.')
|
||||||
|
# Confirm incoming shipment.
|
||||||
|
picking_in.action_confirm()
|
||||||
|
# Check incoming shipment move lines state.
|
||||||
|
for move in picking_in.move_lines:
|
||||||
|
self.assertEqual(move.state, 'assigned', 'Wrong state of move line.')
|
||||||
|
|
||||||
|
# Check incoming shipment move lines state.
|
||||||
|
for move in picking_pack.move_lines:
|
||||||
|
self.assertEqual(move.state, 'draft', 'Wrong state of move line.')
|
||||||
|
# Confirm incoming shipment.
|
||||||
|
picking_pack.action_confirm()
|
||||||
|
# Check incoming shipment move lines state.
|
||||||
|
for move in picking_pack.move_lines:
|
||||||
|
self.assertEqual(move.state, 'waiting', 'Wrong state of move line.')
|
||||||
|
|
||||||
|
# Check incoming shipment move lines state.
|
||||||
|
for move in picking_out.move_lines:
|
||||||
|
self.assertEqual(move.state, 'draft', 'Wrong state of move line.')
|
||||||
|
# Confirm incoming shipment.
|
||||||
|
picking_out.action_confirm()
|
||||||
|
# Check incoming shipment move lines state.
|
||||||
|
for move in picking_out.move_lines:
|
||||||
|
self.assertEqual(move.state, 'waiting', 'Wrong state of move line.')
|
||||||
|
|
||||||
|
# Set the quantity done on the pack operation
|
||||||
|
picking_in.pack_operation_product_ids.qty_done = 3.0
|
||||||
|
# Put in a pack
|
||||||
|
picking_in.put_in_pack()
|
||||||
|
# Get the new package
|
||||||
|
picking_in_package = picking_in.pack_operation_ids.result_package_id
|
||||||
|
# Validate picking
|
||||||
|
picking_in.do_new_transfer()
|
||||||
|
|
||||||
|
# Check first picking state changed to done
|
||||||
|
for move in picking_in.move_lines:
|
||||||
|
self.assertEqual(move.state, 'done', 'Wrong state of move line.')
|
||||||
|
# Check next picking state changed to 'assigned'
|
||||||
|
for move in picking_pack.move_lines:
|
||||||
|
self.assertEqual(move.state, 'assigned', 'Wrong state of move line.')
|
||||||
|
|
||||||
|
# set the pack in pack operation to 'done'
|
||||||
|
for pack in picking_pack.pack_operation_pack_ids:
|
||||||
|
pack.qty_done = 1.0
|
||||||
|
|
||||||
|
# Put in a pack
|
||||||
|
picking_pack.put_in_pack()
|
||||||
|
# Get the new package
|
||||||
|
picking_pack_package = picking_pack.pack_operation_ids.result_package_id
|
||||||
|
# Validate picking
|
||||||
|
picking_pack.do_new_transfer()
|
||||||
|
|
||||||
|
# Check second picking state changed to done
|
||||||
|
for move in picking_pack.move_lines:
|
||||||
|
self.assertEqual(move.state, 'done', 'Wrong state of move line.')
|
||||||
|
# Check next picking state changed to 'assigned'
|
||||||
|
for move in picking_out.move_lines:
|
||||||
|
self.assertEqual(move.state, 'assigned', 'Wrong state of move line.')
|
||||||
|
|
||||||
|
# set the pack in pack operation to 'done'
|
||||||
|
for pack in picking_out.pack_operation_pack_ids:
|
||||||
|
pack.qty_done = 1.0
|
||||||
|
|
||||||
|
# Validate picking
|
||||||
|
picking_out.do_new_transfer()
|
||||||
|
|
||||||
|
# check all pickings are done
|
||||||
|
for move in picking_in.move_lines:
|
||||||
|
self.assertEqual(move.state, 'done', 'Wrong state of move line.')
|
||||||
|
for move in picking_pack.move_lines:
|
||||||
|
self.assertEqual(move.state, 'done', 'Wrong state of move line.')
|
||||||
|
for move in picking_out.move_lines:
|
||||||
|
self.assertEqual(move.state, 'done', 'Wrong state of move line.')
|
||||||
|
|
||||||
|
# Check picking_in_package is in picking_pack_package
|
||||||
|
self.assertEqual(picking_in_package.parent_id.id, picking_pack_package.id, 'The package created in the picking in is not in the one created in picking pack')
|
||||||
|
# Check that both packages are in the customer location
|
||||||
|
self.assertEqual(picking_pack_package.location_id.id, self.customer_location, 'The package created in picking pack is not in the customer location')
|
||||||
|
self.assertEqual(picking_in_package.location_id.id, self.customer_location, 'The package created in picking in is not in the customer location')
|
||||||
|
# Check that we have a quant in customer location, for the productA with qty 3
|
||||||
|
quant = self.StockQuantObj.search([('location_id', '=', self.customer_location), ('product_id', '=', self.productA.id)])
|
||||||
|
self.assertTrue(quant.id, 'There is no quant in customer location for productA')
|
||||||
|
self.assertEqual(quant.qty, 3.0, 'The quant in customer location for productA has not a quantity of 3.0')
|
||||||
|
# Check that the parent package of the quant is the picking_in_package
|
||||||
|
self.assertEqual(quant.package_id.id, picking_in_package.id, 'The quant in customer location is not in its package created in picking in')
|
||||||
|
|||||||
@@ -262,7 +262,7 @@
|
|||||||
<field name="nbr_reordering_rules" widget="statinfo"/>
|
<field name="nbr_reordering_rules" widget="statinfo"/>
|
||||||
</button>
|
</button>
|
||||||
<button name="%(product_open_orderpoint)d" type="action"
|
<button name="%(product_open_orderpoint)d" type="action"
|
||||||
attrs="{'invisible':['|',('type', '!=', ['product', 'consu']),('nbr_reordering_rules', '!=', 1)]}"
|
attrs="{'invisible':['|',('type', 'not in', ['product', 'consu']),('nbr_reordering_rules', '!=', 1)]}"
|
||||||
class="oe_stat_button" icon="fa-refresh">
|
class="oe_stat_button" icon="fa-refresh">
|
||||||
<div class="o_form_field o_stat_info mr4">
|
<div class="o_form_field o_stat_info mr4">
|
||||||
<span class="o_stat_text">Min :</span>
|
<span class="o_stat_text">Min :</span>
|
||||||
|
|||||||
@@ -936,12 +936,19 @@ $.summernote.pluginEvents.insertTable = function (event, editor, layoutInfo, sDi
|
|||||||
var dimension = sDim.split('x');
|
var dimension = sDim.split('x');
|
||||||
var r = range.create();
|
var r = range.create();
|
||||||
if (!r) return;
|
if (!r) return;
|
||||||
r = r.deleteContents();
|
r = r.deleteContents(true);
|
||||||
|
|
||||||
var isBodyContainer = dom.isBodyContainer;
|
var table = editor.table.createTable(dimension[0], dimension[1]);
|
||||||
dom.isBodyContainer = dom.isNotBreakable;
|
var parent = r.sc;
|
||||||
r.insertNode(editor.table.createTable(dimension[0], dimension[1]));
|
while (dom.isText(parent.parentNode) || dom.isRemovableEmptyNode(parent.parentNode)) {
|
||||||
dom.isBodyContainer = isBodyContainer;
|
parent = parent.parentNode;
|
||||||
|
}
|
||||||
|
var node = dom.splitTree(parent, {'node': r.sc, 'offset': r.so}) || r.sc;
|
||||||
|
node.parentNode.insertBefore(table, node);
|
||||||
|
|
||||||
|
if ($(node).text() === '' || node.textContent === '\u00A0') {
|
||||||
|
node.parentNode.removeChild(node);
|
||||||
|
}
|
||||||
|
|
||||||
editor.afterCommand($editable);
|
editor.afterCommand($editable);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
France, 12-11-2016
|
||||||
|
|
||||||
|
I hereby agree to the terms of the Odoo Individual Contributor License
|
||||||
|
Agreement v1.0.
|
||||||
|
|
||||||
|
I declare that I am authorized and able to make this agreement and sign this
|
||||||
|
declaration.
|
||||||
|
|
||||||
|
Signed,
|
||||||
|
|
||||||
|
Florent de Labarre florent.mirieu@gmail.com https://github.com/fmdl
|
||||||
@@ -265,7 +265,7 @@ class IrHttp(models.AbstractModel):
|
|||||||
module_path = os.path.join(os.path.normpath(module_path), '') # join ensures the path ends with '/'
|
module_path = os.path.join(os.path.normpath(module_path), '') # join ensures the path ends with '/'
|
||||||
module_resource_path = os.path.normpath(module_resource_path)
|
module_resource_path = os.path.normpath(module_resource_path)
|
||||||
if module_resource_path.startswith(module_path):
|
if module_resource_path.startswith(module_path):
|
||||||
with open(module_resource_path, 'r') as f:
|
with open(module_resource_path, 'rb') as f:
|
||||||
content = base64.b64encode(f.read())
|
content = base64.b64encode(f.read())
|
||||||
last_update = str(os.path.getmtime(module_resource_path))
|
last_update = str(os.path.getmtime(module_resource_path))
|
||||||
|
|
||||||
|
|||||||
@@ -703,7 +703,7 @@ class Module(models.Model):
|
|||||||
to_install = self.search([('name', 'in', urls.keys()), ('state', '=', 'uninstalled')])
|
to_install = self.search([('name', 'in', urls.keys()), ('state', '=', 'uninstalled')])
|
||||||
post_install_action = to_install.button_immediate_install()
|
post_install_action = to_install.button_immediate_install()
|
||||||
|
|
||||||
if installed:
|
if installed or to_install:
|
||||||
# in this case, force server restart to reload python code...
|
# in this case, force server restart to reload python code...
|
||||||
self._cr.commit()
|
self._cr.commit()
|
||||||
odoo.service.server.restart()
|
odoo.service.server.restart()
|
||||||
|
|||||||
Reference in New Issue
Block a user