Skip to content

Commit

Permalink
Merge remote-tracking branch 'odoo/11.0' into 11.0
Browse files Browse the repository at this point in the history
  • Loading branch information
OCA-git-bot committed Mar 28, 2019
2 parents 9afc6ca + d3453f7 commit 438d3b5
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 14 deletions.
12 changes: 8 additions & 4 deletions addons/account/models/account_bank_statement.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,17 @@ def button_confirm_bank(self):
statements = self.filtered(lambda r: r.state == 'open')
for statement in statements:
moves = self.env['account.move']
# `line.journal_entry_ids` gets invalidated from the cache during the loop
# because new move lines are being created at each iteration.
# The below dict is to prevent the ORM to permanently refetch `line.journal_entry_ids`
line_journal_entries = {line: line.journal_entry_ids for line in statement.line_ids}
for st_line in statement.line_ids:
if st_line.account_id and not st_line.journal_entry_ids.ids:
journal_entries = line_journal_entries[st_line]
if st_line.account_id and not journal_entries.ids:
st_line.fast_counterpart_creation()
elif not st_line.journal_entry_ids.ids and not statement.currency_id.is_zero(st_line.amount):
elif not journal_entries.ids and not statement.currency_id.is_zero(st_line.amount):
raise UserError(_('All the account entries lines must be processed in order to close the statement.'))
for aml in st_line.journal_entry_ids:
moves |= aml.move_id
moves = statement.mapped('line_ids.journal_entry_ids.move_id')
if moves:
moves.filtered(lambda m: m.state != 'posted').post()
statement.message_post(body=_('Statement %s confirmed, journal items were created.') % (statement.name,))
Expand Down
5 changes: 3 additions & 2 deletions addons/account/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -1904,12 +1904,13 @@ def create(self, vals):
# Get value of matched percentage from both move before reconciliating
lines = self.env['account.move.line'].browse(aml)
lines._payment_invoice_match()
if lines[0].account_id.internal_type in ('receivable', 'payable'):
tax_cash_basis_entry = not self.env.context.get('skip_tax_cash_basis_entry') and lines[0].account_id.internal_type in ('receivable', 'payable')
if tax_cash_basis_entry:
percentage_before_rec = lines._get_matched_percentage()
# Reconcile
res = super(AccountPartialReconcile, self).create(vals)
# if the reconciliation is a matching on a receivable or payable account, eventually create a tax cash basis entry
if lines[0].account_id.internal_type in ('receivable', 'payable'):
if tax_cash_basis_entry:
res.create_tax_cash_basis_entry(percentage_before_rec)
res._compute_partial_lines()
return res
Expand Down
10 changes: 7 additions & 3 deletions addons/hw_escpos/escpos/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

""" ESC/POS Commands (Constants) """

# Control characters
ESC = '\x1b'

# Feed control sequences
CTL_LF = '\x0a' # Print and line feed
CTL_FF = '\x0c' # Form feed
Expand All @@ -19,9 +22,10 @@
HW_INIT = '\x1b\x40' # Clear data in buffer and reset modes
HW_SELECT = '\x1b\x3d\x01' # Printer select
HW_RESET = '\x1b\x3f\x0a\x00' # Reset printer hardware
# Cash Drawer
CD_KICK_2 = '\x1b\x70\x00' # Sends a pulse to pin 2 []
CD_KICK_5 = '\x1b\x70\x01' # Sends a pulse to pin 5 []
# Cash Drawer (ESC p <pin> <on time: 2*ms> <off time: 2*ms>)
_CASH_DRAWER = lambda m, t1='', t2='': ESC + 'p' + m + chr(t1) + chr(t2)
CD_KICK_2 = _CASH_DRAWER('\x00', 50, 50) # Sends a pulse to pin 2 []
CD_KICK_5 = _CASH_DRAWER('\x01', 50, 50) # Sends a pulse to pin 5 []
# Paper
PAPER_FULL_CUT = '\x1d\x56\x00' # Full cut paper
PAPER_PART_CUT = '\x1d\x56\x01' # Partial cut paper
Expand Down
9 changes: 8 additions & 1 deletion addons/point_of_sale/models/pos_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ def _get_pos_anglo_saxon_price_unit(self, product, partner_id, quantity):
return - price_unit

def _reconcile_payments(self):
cash_basis_percentage_before_rec = {move: move.line_ids._get_matched_percentage() for move in self.mapped('account_move')}
for order in self:
aml = order.statement_ids.mapped('journal_entry_ids') | order.account_move.line_ids | order.invoice_id.move_id.line_ids
aml = aml.filtered(lambda r: not r.reconciled and r.account_id.internal_type == 'receivable' and r.partner_id == order.partner_id.commercial_partner_id)
Expand All @@ -490,7 +491,7 @@ def _reconcile_payments(self):
# Cash returns will be well reconciled
# Whereas freight returns won't be
# "c'est la vie..."
aml.reconcile()
aml.with_context(skip_tax_cash_basis_entry=True).reconcile()
except Exception:
# There might be unexpected situations where the automatic reconciliation won't
# work. We don't want the user to be blocked because of this, since the automatic
Expand All @@ -499,6 +500,12 @@ def _reconcile_payments(self):
# It may be interesting to have the Traceback logged anyway
# for debugging and support purposes
_logger.exception('Reconciliation did not work for order %s', order.name)
for move in self.mapped('account_move'):
partial_reconcile = self.env['account.partial.reconcile'].search([
'|',
('credit_move_id.move_id', '=', move.id),
('debit_move_id.move_id', '=', move.id)], limit=1)
partial_reconcile.create_tax_cash_basis_entry(cash_basis_percentage_before_rec[move])

def _filtered_for_reconciliation(self):
filter_states = ['invoiced', 'done']
Expand Down
3 changes: 2 additions & 1 deletion addons/point_of_sale/models/pos_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,14 +274,15 @@ def action_pos_session_close(self):
for session in self:
company_id = session.config_id.company_id.id
ctx = dict(self.env.context, force_company=company_id, company_id=company_id)
ctx_notrack = dict(ctx, mail_notrack=True)
for st in session.statement_ids:
if abs(st.difference) > st.journal_id.amount_authorized_diff:
# The pos manager can close statements with maximums.
if not self.user_has_groups("point_of_sale.group_pos_manager"):
raise UserError(_("Your ending balance is too different from the theoretical cash closing (%.2f), the maximum allowed is: %.2f. You can contact your manager to force it.") % (st.difference, st.journal_id.amount_authorized_diff))
if (st.journal_id.type not in ['bank', 'cash']):
raise UserError(_("The type of the journal for your payment method should be bank or cash "))
st.with_context(ctx).sudo().button_confirm_bank()
st.with_context(ctx_notrack).sudo().button_confirm_bank()
self.with_context(ctx)._confirm_orders()
self.write({'state': 'closed'})
return {
Expand Down
1 change: 0 additions & 1 deletion addons/product/views/product_template_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
<field name="image_small"/>
<field name="lst_price"/>
<field name="product_variant_count"/>
<field name="product_variant_ids"/>
<field name="currency_id"/>
<templates>
<t t-name="kanban-box">
Expand Down
6 changes: 4 additions & 2 deletions addons/web/static/src/js/views/calendar/calendar_model.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ return AbstractModel.extend({
.utc();
} else {
// default hours in the user's timezone
start.hours(7).add(-this.getSession().getTZOffset(start), 'minutes');
end.hours(19).add(-this.getSession().getTZOffset(end), 'minutes');
start.hours(7);
end.hours(19);
}
start.add(-this.getSession().getTZOffset(start), 'minutes');
end.add(-this.getSession().getTZOffset(end), 'minutes');
}
} else {
start.add(-this.getSession().getTZOffset(start), 'minutes');
Expand Down
54 changes: 54 additions & 0 deletions addons/web/static/tests/views/calendar_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2053,6 +2053,60 @@ QUnit.module('Views', {
calendar.destroy();
});

QUnit.test('timezone does not affect drag and drop', function (assert) {
assert.expect(6);

var calendar = createView({
View: CalendarView,
model: 'event',
data: this.data,
arch:
'<calendar date_start="start" mode="month">'+
'<field name="name"/>'+
'<field name="start"/>'+
'</calendar>',
archs: archs,
viewOptions: {
initialDate: initialDate,
},
mockRPC: function (route, args) {
if (args.method === "write") {
assert.deepEqual(args.args[0], [6], "event 6 is moved")
assert.deepEqual(args.args[1].start, "2016-11-29 08:00:00",
"event moved to 27th nov 16h00 +40 hours timezone")
}
return this._super(route, args);
},
session: {
getTZOffset: function () {
return -2400; // 40 hours timezone
},
},
});

var events = calendar.$('.fc-event').map(function () {
return $(this).text().trim().replace(/\s+/g, '|');
});

assert.strictEqual(events[0], "event|1|12/09/2016|08:00:00");
assert.strictEqual(events[5], "event|6|12/16/2016|16:00:00");

// Move event 6 as on first day of month view (27th november 2016)
testUtils.dragAndDrop(
calendar.$('.fc-event').eq(5),
calendar.$('.fc-day-top').first()
);

var events = calendar.$('.fc-event').map(function () {
return $(this).text().trim().replace(/\s+/g, '|');
});

assert.strictEqual(events[0], "event|6|11/27/2016|16:00:00");
assert.strictEqual(events[1], "event|1|12/09/2016|08:00:00");

calendar.destroy();
});

QUnit.test('form_view_id attribute works (for creating events)', function (assert) {
assert.expect(1);

Expand Down

0 comments on commit 438d3b5

Please sign in to comment.