diff options
| author | Christophe Simonis <chs@odoo.com> | 2018-01-24 13:24:02 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2018-01-24 13:24:02 +0100 |
| commit | 21c2f519a2ba6be5dc805b8207bb3e82334b23f3 (patch) | |
| tree | 69179d275520073011620c9f5ebc4218e51bbcfb | |
| parent | 3d673b5900805ffa4315b1b0385ff66f8e5702ee (diff) | |
| parent | c0fa5228d8e1647413c2901728b4c05971185079 (diff) | |
[MERGE] forward port branch 10.0 up to c0fa5228d8e
| -rw-r--r-- | addons/account_accountant/models/res_config.py | 15 | ||||
| -rw-r--r-- | addons/point_of_sale/models/pos_order.py | 13 | ||||
| -rw-r--r-- | addons/point_of_sale/security/ir.model.access.csv | 2 | ||||
| -rw-r--r-- | addons/stock/models/stock_inventory.py | 4 | ||||
| -rw-r--r-- | addons/website_event_track/controllers/main.py | 4 | ||||
| -rw-r--r-- | addons/website_event_track/views/website_event_track_templates.xml | 4 | ||||
| -rw-r--r-- | doc/cla/individual/sergeiruzkiicode.md | 11 | ||||
| -rw-r--r-- | odoo/addons/base/res/res_country_data.xml | 4 | ||||
| -rw-r--r-- | odoo/addons/base/res/res_currency_data.xml | 7 | ||||
| -rw-r--r-- | odoo/addons/base/res/res_currency_demo.xml | 6 | ||||
| -rw-r--r-- | odoo/addons/base/res/res_users.py | 8 | ||||
| -rw-r--r-- | odoo/http.py | 16 |
12 files changed, 76 insertions, 18 deletions
diff --git a/addons/account_accountant/models/res_config.py b/addons/account_accountant/models/res_config.py index 3059bbd2d93..d8cc8562f8e 100644 --- a/addons/account_accountant/models/res_config.py +++ b/addons/account_accountant/models/res_config.py @@ -7,7 +7,8 @@ from odoo import fields, models class AccountConfigSettings(models.TransientModel): _inherit = 'account.config.settings' - fiscalyear_last_day = fields.Integer(related='company_id.fiscalyear_last_day', default=31) + fiscalyear_last_day = fields.Integer(related='company_id.fiscalyear_last_day', + default=lambda self: self._default_fiscalyear_last_day()) fiscalyear_last_month = fields.Selection([ (1, 'January'), (2, 'February'), @@ -20,8 +21,10 @@ class AccountConfigSettings(models.TransientModel): (9, 'September'), (10, 'October'), (11, 'November'), - (12, 'December') - ], related='company_id.fiscalyear_last_month', default=12) + (12, 'December')], + related='company_id.fiscalyear_last_month', + default=lambda self: self._default_fiscalyear_last_month()) + period_lock_date = fields.Date(related='company_id.period_lock_date') fiscalyear_lock_date = fields.Date(related='company_id.fiscalyear_lock_date') use_anglo_saxon = fields.Boolean(string='Anglo-Saxon Accounting', related='company_id.anglo_saxon_accounting') @@ -33,3 +36,9 @@ class AccountConfigSettings(models.TransientModel): 'account.journal', related='company_id.tax_cash_basis_journal_id', string="Tax Cash Basis Journal",) + + def _default_fiscalyear_last_day(self): + return self.env.user.company_id.fiscalyear_last_day or 31 + + def _default_fiscalyear_last_month(self): + return self.env.user.company_id.fiscalyear_last_month or 12 diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index 41113553b36..8f28ec09a82 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -339,15 +339,22 @@ class PosOrder(models.Model): 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) + + # Reconcile returns first + # to avoid mixing up the credit of a payment and the credit of a return + # in the receivable account + aml_returns = aml.filtered(lambda l: (l.journal_id.type == 'sale' and l.credit) or (l.journal_id.type != 'sale' and l.debit)) try: - aml.reconcile() + aml_returns.reconcile() + (aml - aml_returns).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 # reconciliation is introduced for convenience, not for mandatory accounting # reasons. - _logger.error('Reconciliation did not work for order %s', order.name) - continue + # 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) def _default_session(self): return self.env['pos.session'].search([('state', '=', 'opened'), ('user_id', '=', self.env.uid)], limit=1) diff --git a/addons/point_of_sale/security/ir.model.access.csv b/addons/point_of_sale/security/ir.model.access.csv index 1e6f9b4e619..d9759520b4c 100644 --- a/addons/point_of_sale/security/ir.model.access.csv +++ b/addons/point_of_sale/security/ir.model.access.csv @@ -27,7 +27,7 @@ access_product_category_manager,product.category manager,product.model_product_c access_product_pricelist_manager,product.pricelist manager,product.model_product_pricelist,group_pos_manager,1,0,0,0
access_pos_session_user,pos.session user,model_pos_session,group_pos_user,1,1,1,0
access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,1,0,0
-access_pos_config_manager,pos.config user,model_pos_config,group_pos_manager,1,1,1,0
+access_pos_config_manager,pos.config manager,model_pos_config,group_pos_manager,1,1,1,1
access_product_category_pos_manager,pos.category manager,model_pos_category,group_pos_manager,1,1,1,1
access_product_category_pos_user,pos.category user,model_pos_category,group_pos_user,1,0,0,0
access_barcode_nomenclature_pos_user,barcode.nomenclature.pos.user,barcodes.model_barcode_nomenclature,group_pos_user,1,0,0,0
diff --git a/addons/stock/models/stock_inventory.py b/addons/stock/models/stock_inventory.py index c6bfc0549dd..81d273da48e 100644 --- a/addons/stock/models/stock_inventory.py +++ b/addons/stock/models/stock_inventory.py @@ -454,9 +454,9 @@ class InventoryLine(models.Model): continue diff = line.theoretical_qty - line.product_qty if diff < 0: # found more than expected - vals = self._get_move_values(abs(diff), line.product_id.property_stock_inventory.id, line.location_id.id) + vals = line._get_move_values(abs(diff), line.product_id.property_stock_inventory.id, line.location_id.id) else: - vals = self._get_move_values(abs(diff), line.location_id.id, line.product_id.property_stock_inventory.id) + vals = line._get_move_values(abs(diff), line.location_id.id, line.product_id.property_stock_inventory.id) move = moves.create(vals) if diff > 0: diff --git a/addons/website_event_track/controllers/main.py b/addons/website_event_track/controllers/main.py index e4256f30452..52efc7b38d2 100644 --- a/addons/website_event_track/controllers/main.py +++ b/addons/website_event_track/controllers/main.py @@ -15,7 +15,7 @@ class WebsiteEventTrackController(http.Controller): @http.route(['''/event/<model("event.event"):event>/track/<model("event.track", "[('event_id','=',event[0])]"):track>'''], type='http', auth="public", website=True) def event_track_view(self, event, track, **post): - track = track.sudo() + track = track.sudo().with_context(tz=event.date_tz or 'UTC') values = {'track': track, 'event': track.event_id, 'main_object': track} return request.render("website_event_track.track_view", values) @@ -67,6 +67,7 @@ class WebsiteEventTrackController(http.Controller): @http.route(['''/event/<model("event.event", "[('show_tracks','=',1)]"):event>/agenda'''], type='http', auth="public", website=True) def event_agenda(self, event, tag=None, **post): + event = event.with_context(tz=event.date_tz or 'UTC') local_tz = pytz.timezone(event.date_tz or 'UTC') days_tracks = collections.defaultdict(lambda: []) for track in event.track_ids.sorted(lambda track: (track.date, bool(track.location_id))): @@ -99,6 +100,7 @@ class WebsiteEventTrackController(http.Controller): '''/event/<model("event.event", "[('show_tracks','=',1)]"):event>/track/tag/<model("event.track.tag"):tag>''' ], type='http', auth="public", website=True) def event_tracks(self, event, tag=None, **post): + event = event.with_context(tz=event.date_tz or 'UTC') searches = {} if tag: searches.update(tag=tag.id) diff --git a/addons/website_event_track/views/website_event_track_templates.xml b/addons/website_event_track/views/website_event_track_templates.xml index 2e289cc92c7..6220b541850 100644 --- a/addons/website_event_track/views/website_event_track_templates.xml +++ b/addons/website_event_track/views/website_event_track_templates.xml @@ -250,7 +250,9 @@ </div> <div class="panel-body"> <b>Date</b><br/> - <span t-field="track.date" t-options='{"hide_seconds":"True"}'/><br/> + <span t-field="track.date" t-options='{"hide_seconds":"True"}'/> + <t t-if="event.date_tz">(<span t-field="event.date_tz"/>)</t> + <br/> <b>Duration</b><br/> <span t-field="track.duration" t-options='{"widget": "duration", "unit": "hour", "round": "minute"}'/><br/> <b>Location</b><br/> diff --git a/doc/cla/individual/sergeiruzkiicode.md b/doc/cla/individual/sergeiruzkiicode.md new file mode 100644 index 00000000000..44af0359a97 --- /dev/null +++ b/doc/cla/individual/sergeiruzkiicode.md @@ -0,0 +1,11 @@ +Belarus, 2017-01-17 + +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, + +Sergei Ruzki sergei.ruzki@icode.by https://github.com/sergeiruzkiicode diff --git a/odoo/addons/base/res/res_country_data.xml b/odoo/addons/base/res/res_country_data.xml index 19748318218..c56247a98cb 100644 --- a/odoo/addons/base/res/res_country_data.xml +++ b/odoo/addons/base/res/res_country_data.xml @@ -258,8 +258,8 @@ <field name="name">Belarus</field> <field name="code">by</field> <field file="base/static/img/country_flags/by.png" name="image" type="base64" /> - <field name="currency_id" ref="BYR" /> - <field eval="0" name="phone_code" /> + <field name="currency_id" ref="BYN" /> + <field eval="375" name="phone_code" /> </record> <record id="bz" model="res.country"> <field name="name">Belize</field> diff --git a/odoo/addons/base/res/res_currency_data.xml b/odoo/addons/base/res/res_currency_data.xml index 8b108fa978d..8746f4d0b1b 100644 --- a/odoo/addons/base/res/res_currency_data.xml +++ b/odoo/addons/base/res/res_currency_data.xml @@ -408,6 +408,13 @@ <field name="active" eval="False"/> </record> + <record id="BYN" model="res.currency"> + <field name="name">BYN</field> + <field name="symbol">Br</field> + <field name="rounding">0.01</field> + <field name="active" eval="False"/> + </record> + <record id="BZD" model="res.currency"> <field name="name">BZD</field> <field name="symbol">BZ$</field> diff --git a/odoo/addons/base/res/res_currency_demo.xml b/odoo/addons/base/res/res_currency_demo.xml index a6e406e783d..ba316d0a7db 100644 --- a/odoo/addons/base/res/res_currency_demo.xml +++ b/odoo/addons/base/res/res_currency_demo.xml @@ -349,6 +349,12 @@ <field name="rate">10228.19</field> </record> + <record forcecreate="0" id="rateBYN" model="res.currency.rate"> + <field name="currency_id" ref="BYN" /> + <field name="name">2016-07-01</field> + <field name="rate">2.23151</field> + </record> + <record forcecreate="0" id="rateBZD" model="res.currency.rate"> <field name="currency_id" ref="BZD" /> <field name="name">2010-01-01</field> diff --git a/odoo/addons/base/res/res_users.py b/odoo/addons/base/res/res_users.py index 596620a9e52..657bebf58a7 100644 --- a/odoo/addons/base/res/res_users.py +++ b/odoo/addons/base/res/res_users.py @@ -14,6 +14,7 @@ from odoo.exceptions import AccessDenied, AccessError, UserError, ValidationErro from odoo.osv import expression from odoo.service.db import check_super from odoo.tools import partition +from odoo.http import root _logger = logging.getLogger(__name__) @@ -372,6 +373,8 @@ class Users(models.Model): if any(key.startswith('context_') or key in ('lang', 'tz') for key in values): self.context_get.clear_cache(self) if any(key in values for key in ['active'] + USER_PRIVATE_FIELDS): + # force deletion of all sessions for these users + root.session_store.delete_sessions_for_uids(self.ids) db = self._cr.dbname for id in self.ids: self.__uid_cache[db].pop(id, None) @@ -385,7 +388,10 @@ class Users(models.Model): db = self._cr.dbname for id in self.ids: self.__uid_cache[db].pop(id, None) - return super(Users, self).unlink() + res = super(Users, self).unlink() + # force deletion of all sessions for these users + root.session_store.delete_sessions_for_uids(self.ids) + return res @api.model def name_search(self, name='', args=None, operator='ilike', limit=100): diff --git a/odoo/http.py b/odoo/http.py index 56b1f8e6930..46d744f2f36 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -1040,7 +1040,6 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): self.db = db self.uid = uid self.login = login - self.password = password request.uid = uid request.disable_db = False @@ -1055,7 +1054,6 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): """ if not self.db or not self.uid: raise SessionExpiredException("Session expired") - security.check(self.db, self.uid, self.password) def logout(self, keep_db=False): for k in self.keys(): @@ -1068,7 +1066,6 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): self.setdefault("db", None) self.setdefault("uid", None) self.setdefault("login", None) - self.setdefault("password", None) self.setdefault("context", {}) def get_context(self): @@ -1281,6 +1278,17 @@ class DisableCacheMiddleware(object): start_response(status, new_headers) return self.app(environ, start_wrapped) +class OdooSessionStore(werkzeug.contrib.sessions.FilesystemSessionStore): + def delete_sessions_for_uids(self, uids): + # pretty expensive on large session stores, especially non-local! + uids = set(uids) + _logger.info('Deleting all HTTP sessions for UIDs %s', uids) + for sid in self.list(): + s = self.get(sid) + if s.uid and s.uid in uids: + _logger.debug('Deleting session %s', sid) + self.delete(s) + class Root(object): """Root WSGI application for the OpenERP Web Client. """ @@ -1292,7 +1300,7 @@ class Root(object): # Setup http sessions path = odoo.tools.config.session_dir _logger.debug('HTTP sessions stored in: %s', path) - return werkzeug.contrib.sessions.FilesystemSessionStore(path, session_class=OpenERPSession) + return OdooSessionStore(path, session_class=OpenERPSession) @lazy_property def nodb_routing_map(self): |
