[MERGE] forward port branch saas-15 up to d3a040cebe
This commit is contained in:
@@ -591,7 +591,8 @@ class AccountInvoice(models.Model):
|
|||||||
for invoice in self:
|
for invoice in self:
|
||||||
# Delete non-manual tax lines
|
# Delete non-manual tax lines
|
||||||
self._cr.execute("DELETE FROM account_invoice_tax WHERE invoice_id=%s AND manual is False", (invoice.id,))
|
self._cr.execute("DELETE FROM account_invoice_tax WHERE invoice_id=%s AND manual is False", (invoice.id,))
|
||||||
self.invalidate_cache()
|
if self._cr.rowcount:
|
||||||
|
self.invalidate_cache()
|
||||||
|
|
||||||
# Generate one tax line per tax, however many invoice lines it's applied to
|
# Generate one tax line per tax, however many invoice lines it's applied to
|
||||||
tax_grouped = invoice.get_taxes_values()
|
tax_grouped = invoice.get_taxes_values()
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ class AccountMove(models.Model):
|
|||||||
total_amount += amount
|
total_amount += amount
|
||||||
for partial_line in (line.matched_debit_ids + line.matched_credit_ids):
|
for partial_line in (line.matched_debit_ids + line.matched_credit_ids):
|
||||||
total_reconciled += partial_line.amount
|
total_reconciled += partial_line.amount
|
||||||
if float_is_zero(total_amount, precision_rounding=move.currency_id.rounding):
|
precision_currency = move.currency_id or move.company_id.currency_id
|
||||||
|
if float_is_zero(total_amount, precision_rounding=precision_currency.rounding):
|
||||||
move.matched_percentage = 1.0
|
move.matched_percentage = 1.0
|
||||||
else:
|
else:
|
||||||
move.matched_percentage = total_reconciled / total_amount
|
move.matched_percentage = total_reconciled / total_amount
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ class AccountChartTemplate(models.Model):
|
|||||||
for element in in_ids.with_context(lang=None):
|
for element in in_ids.with_context(lang=None):
|
||||||
if value[element.id]:
|
if value[element.id]:
|
||||||
#copy Translation from Source to Destination object
|
#copy Translation from Source to Destination object
|
||||||
xlat_obj.create({
|
xlat_obj._set_ids(
|
||||||
'name': out_ids._name + ',' + in_field,
|
out_ids._name + ',' + in_field,
|
||||||
'type': 'model',
|
'model',
|
||||||
'res_id': out_ids[counter].id,
|
lang,
|
||||||
'lang': lang,
|
out_ids[counter].ids,
|
||||||
'src': element[in_field],
|
value[element.id],
|
||||||
'value': value[element.id],
|
element[in_field]
|
||||||
})
|
)
|
||||||
else:
|
else:
|
||||||
_logger.info('Language: %s. Translation from template: there is no translation available for %s!' % (lang, element[in_field]))
|
_logger.info('Language: %s. Translation from template: there is no translation available for %s!' % (lang, element[in_field]))
|
||||||
counter += 1
|
counter += 1
|
||||||
|
|||||||
@@ -400,6 +400,9 @@ class SaleOrder(models.Model):
|
|||||||
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
|
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
|
||||||
invoices = {}
|
invoices = {}
|
||||||
references = {}
|
references = {}
|
||||||
|
invoices_origin = {}
|
||||||
|
invoices_name = {}
|
||||||
|
|
||||||
for order in self:
|
for order in self:
|
||||||
group_key = order.id if grouped else (order.partner_invoice_id.id, order.currency_id.id)
|
group_key = order.id if grouped else (order.partner_invoice_id.id, order.currency_id.id)
|
||||||
for line in order.order_line.sorted(key=lambda l: l.qty_to_invoice < 0):
|
for line in order.order_line.sorted(key=lambda l: l.qty_to_invoice < 0):
|
||||||
@@ -410,13 +413,14 @@ class SaleOrder(models.Model):
|
|||||||
invoice = inv_obj.create(inv_data)
|
invoice = inv_obj.create(inv_data)
|
||||||
references[invoice] = order
|
references[invoice] = order
|
||||||
invoices[group_key] = invoice
|
invoices[group_key] = invoice
|
||||||
|
invoices_origin[group_key] = [invoice.origin]
|
||||||
|
invoices_name[group_key] = [invoice.name]
|
||||||
elif group_key in invoices:
|
elif group_key in invoices:
|
||||||
vals = {}
|
if order.name not in invoices_origin[group_key]:
|
||||||
if order.name not in invoices[group_key].origin.split(', '):
|
invoices_origin[group_key].append(order.name)
|
||||||
vals['origin'] = invoices[group_key].origin + ', ' + order.name
|
if order.client_order_ref and order.client_order_ref not in invoices_name[group_key]:
|
||||||
if order.client_order_ref and order.client_order_ref not in invoices[group_key].name.split(', ') and order.client_order_ref != invoices[group_key].name:
|
invoices_name[group_key].append(order.client_order_ref)
|
||||||
vals['name'] = invoices[group_key].name + ', ' + order.client_order_ref
|
|
||||||
invoices[group_key].write(vals)
|
|
||||||
if line.qty_to_invoice > 0:
|
if line.qty_to_invoice > 0:
|
||||||
line.invoice_line_create(invoices[group_key].id, line.qty_to_invoice)
|
line.invoice_line_create(invoices[group_key].id, line.qty_to_invoice)
|
||||||
elif line.qty_to_invoice < 0 and final:
|
elif line.qty_to_invoice < 0 and final:
|
||||||
@@ -426,6 +430,10 @@ class SaleOrder(models.Model):
|
|||||||
if order not in references[invoices[group_key]]:
|
if order not in references[invoices[group_key]]:
|
||||||
references[invoices[group_key]] |= order
|
references[invoices[group_key]] |= order
|
||||||
|
|
||||||
|
for group_key in invoices:
|
||||||
|
invoices[group_key].write({'name': ', '.join(invoices_name[group_key]),
|
||||||
|
'origin': ', '.join(invoices_origin[group_key])})
|
||||||
|
|
||||||
if not invoices:
|
if not invoices:
|
||||||
raise UserError(_('There is no invoiceable line.'))
|
raise UserError(_('There is no invoiceable line.'))
|
||||||
|
|
||||||
|
|||||||
@@ -150,11 +150,14 @@ class Warehouse(models.Model):
|
|||||||
# If another partner assigned
|
# If another partner assigned
|
||||||
if vals.get('partner_id'):
|
if vals.get('partner_id'):
|
||||||
warehouses._update_partner_data(vals['partner_id'], vals.get('company_id'))
|
warehouses._update_partner_data(vals['partner_id'], vals.get('company_id'))
|
||||||
|
|
||||||
res = super(Warehouse, self).write(vals)
|
res = super(Warehouse, self).write(vals)
|
||||||
|
|
||||||
# check if we need to delete and recreate route
|
# check if we need to delete and recreate route
|
||||||
if vals.get('reception_steps') or vals.get('delivery_steps'):
|
if vals.get('reception_steps') or vals.get('delivery_steps'):
|
||||||
warehouses._update_routes()
|
route_vals = warehouses._update_routes()
|
||||||
|
if route_vals:
|
||||||
|
self.write(route_vals)
|
||||||
|
|
||||||
if vals.get('resupply_wh_ids') and not vals.get('resupply_route_ids'):
|
if vals.get('resupply_wh_ids') and not vals.get('resupply_route_ids'):
|
||||||
for warehouse in warehouses:
|
for warehouse in warehouses:
|
||||||
@@ -280,7 +283,7 @@ class Warehouse(models.Model):
|
|||||||
reception_route.pull_ids.write({'active': False})
|
reception_route.pull_ids.write({'active': False})
|
||||||
reception_route.push_ids.write({'active': False})
|
reception_route.push_ids.write({'active': False})
|
||||||
else:
|
else:
|
||||||
reception_route = self.env['stock.location.route'].create(warehouse._get_reception_delivery_route_values(warehouse.reception_steps))
|
warehouse.reception_route_id = reception_route = self.env['stock.location.route'].create(warehouse._get_reception_delivery_route_values(warehouse.reception_steps))
|
||||||
# push / procurement (pull) rules for reception
|
# push / procurement (pull) rules for reception
|
||||||
routings = routes_data[warehouse.id][warehouse.reception_steps]
|
routings = routes_data[warehouse.id][warehouse.reception_steps]
|
||||||
push_rules_list, pull_rules_list = warehouse._get_push_pull_rules_values(
|
push_rules_list, pull_rules_list = warehouse._get_push_pull_rules_values(
|
||||||
@@ -593,11 +596,18 @@ class Warehouse(models.Model):
|
|||||||
routes_data = self.get_routes_dict()
|
routes_data = self.get_routes_dict()
|
||||||
# change the default source and destination location and (de)activate operation types
|
# change the default source and destination location and (de)activate operation types
|
||||||
self._update_picking_type()
|
self._update_picking_type()
|
||||||
self._create_or_update_delivery_route(routes_data)
|
delivery_route = self._create_or_update_delivery_route(routes_data)
|
||||||
self._create_or_update_reception_route(routes_data)
|
reception_route = self._create_or_update_reception_route(routes_data)
|
||||||
self._create_or_update_crossdock_route(routes_data)
|
crossdock_route = self._create_or_update_crossdock_route(routes_data)
|
||||||
self._create_or_update_mto_pull(routes_data)
|
mto_pull = self._create_or_update_mto_pull(routes_data)
|
||||||
return True
|
|
||||||
|
return {
|
||||||
|
'route_ids': [(4, route.id) for route in reception_route | delivery_route | crossdock_route],
|
||||||
|
'mto_pull_id': mto_pull.id,
|
||||||
|
'reception_route_id': reception_route.id,
|
||||||
|
'delivery_route_id': delivery_route.id,
|
||||||
|
'crossdock_route_id': crossdock_route.id,
|
||||||
|
}
|
||||||
|
|
||||||
@api.one
|
@api.one
|
||||||
def _update_picking_type(self):
|
def _update_picking_type(self):
|
||||||
|
|||||||
@@ -119,6 +119,13 @@ def init_logger():
|
|||||||
if dirname and not os.path.isdir(dirname):
|
if dirname and not os.path.isdir(dirname):
|
||||||
os.makedirs(dirname)
|
os.makedirs(dirname)
|
||||||
if tools.config['logrotate'] is not False:
|
if tools.config['logrotate'] is not False:
|
||||||
|
if tools.config['workers'] > 1:
|
||||||
|
# TODO: fallback to regular file logging in master for safe(r) defaults?
|
||||||
|
#
|
||||||
|
# Doing so here would be a good idea but also might break
|
||||||
|
# situations were people do log-shipping of rotated data?
|
||||||
|
_logger.warn("WARNING: built-in log rotation is not reliable in multi-worker scenarios and may incur significant data loss. "
|
||||||
|
"It is strongly recommended to use an external log rotation utility or use system loggers (--syslog) instead.")
|
||||||
handler = logging.handlers.TimedRotatingFileHandler(filename=logf, when='D', interval=1, backupCount=30)
|
handler = logging.handlers.TimedRotatingFileHandler(filename=logf, when='D', interval=1, backupCount=30)
|
||||||
elif os.name == 'posix':
|
elif os.name == 'posix':
|
||||||
handler = logging.handlers.WatchedFileHandler(logf)
|
handler = logging.handlers.WatchedFileHandler(logf)
|
||||||
|
|||||||
+4
-3
@@ -45,11 +45,12 @@ class _Cleaner(clean.Cleaner):
|
|||||||
_style_whitelist = [
|
_style_whitelist = [
|
||||||
'font-size', 'font-family', 'font-weight', 'background-color', 'color', 'text-align',
|
'font-size', 'font-family', 'font-weight', 'background-color', 'color', 'text-align',
|
||||||
'line-height', 'letter-spacing', 'text-transform', 'text-decoration',
|
'line-height', 'letter-spacing', 'text-transform', 'text-decoration',
|
||||||
|
'float', 'vertical-align',
|
||||||
'padding', 'padding-top', 'padding-left', 'padding-bottom', 'padding-right',
|
'padding', 'padding-top', 'padding-left', 'padding-bottom', 'padding-right',
|
||||||
'margin', 'margin-top', 'margin-left', 'margin-bottom', 'margin-right'
|
'margin', 'margin-top', 'margin-left', 'margin-bottom', 'margin-right',
|
||||||
# box model
|
# box model
|
||||||
'border', 'border-color', 'border-radius', 'border-style', 'height',
|
'border', 'border-color', 'border-radius', 'border-style', 'border-width',
|
||||||
'margin', 'padding', 'width', 'max-width', 'min-width',
|
'height', 'margin', 'padding', 'width', 'max-width', 'min-width',
|
||||||
# tables
|
# tables
|
||||||
'border-collapse', 'border-spacing', 'caption-side', 'empty-cells', 'table-layout']
|
'border-collapse', 'border-spacing', 'caption-side', 'empty-cells', 'table-layout']
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user