[MERGE] forward port branch 11.0 up to 51225c9b9f

This commit is contained in:
Christophe Simonis
2018-08-14 18:59:57 +02:00
28 changed files with 107 additions and 49 deletions
+16
View File
@@ -1231,6 +1231,21 @@ class AccountMoveLine(models.Model):
action['domain'] = [('id', 'in', ids)] action['domain'] = [('id', 'in', ids)]
return action return action
@api.multi
def _payment_invoice_match(self):
'''
If a partial reconciliation involves payments and invoices
mark the invoices as paid by the payments
Specifically made for len(self) == 2
'''
if not self:
return
invoice_ids = self.mapped('invoice_id')
payment_ids = self.mapped('payment_id')
if payment_ids and invoice_ids:
payment_ids.write({'invoice_ids': [(4, inv.id, False) for inv in invoice_ids]})
class AccountPartialReconcile(models.Model): class AccountPartialReconcile(models.Model):
_name = "account.partial.reconcile" _name = "account.partial.reconcile"
@@ -1530,6 +1545,7 @@ class AccountPartialReconcile(models.Model):
aml.append(vals['credit_move_id']) aml.append(vals['credit_move_id'])
# Get value of matched percentage from both move before reconciliating # Get value of matched percentage from both move before reconciliating
lines = self.env['account.move.line'].browse(aml) lines = self.env['account.move.line'].browse(aml)
lines._payment_invoice_match()
if lines[0].account_id.internal_type in ('receivable', 'payable'): if lines[0].account_id.internal_type in ('receivable', 'payable'):
percentage_before_rec = lines._get_matched_percentage() percentage_before_rec = lines._get_matched_percentage()
# Reconcile # Reconcile
+2 -6
View File
@@ -122,12 +122,8 @@ Best Regards,'''))
@api.model @api.model
def _verify_fiscalyear_last_day(self, company_id, last_day, last_month): def _verify_fiscalyear_last_day(self, company_id, last_day, last_month):
company = self.browse(company_id) # FIXME: Remove this method in master
last_day = last_day or (company and company.fiscalyear_last_day) or 31 return last_day
last_month = last_month or (company and company.fiscalyear_last_month) or 12
current_year = datetime.now().year
last_day_of_month = calendar.monthrange(current_year, last_month)[1]
return last_day > last_day_of_month and last_day_of_month or last_day
@api.multi @api.multi
def compute_fiscalyear_dates(self, date): def compute_fiscalyear_dates(self, date):
-11
View File
@@ -36,17 +36,6 @@ class FinancialYearOpeningWizard(models.TransientModel):
""" Forces fiscal year setup state to 'undone'.""" """ Forces fiscal year setup state to 'undone'."""
self.company_id.account_setup_fy_data_done = False self.company_id.account_setup_fy_data_done = False
@api.multi
def write(self, vals):
if 'fiscalyear_last_day' in vals or 'fiscalyear_last_month' in vals:
for wizard in self:
company = wizard.company_id
vals['fiscalyear_last_day'] = company._verify_fiscalyear_last_day(
company.id,
vals.get('fiscalyear_last_day'),
vals.get('fiscalyear_last_month'))
return super(FinancialYearOpeningWizard, self).write(vals)
class OpeningAccountMoveWizard(models.TransientModel): class OpeningAccountMoveWizard(models.TransientModel):
_name = 'account.opening' _name = 'account.opening'
@@ -127,6 +127,9 @@ class IrModelFieldsAnonymizeWizard(models.TransientModel):
@api.multi @api.multi
def anonymize_database(self): def anonymize_database(self):
"""Sets the 'anonymized' state to defined fields""" """Sets the 'anonymized' state to defined fields"""
# pylint: disable=W0101
raise UserError("""The Odoo Migration Platform no longer accepts anonymized databases.\n
If you wish for your data to remain private during migration, please contact us at upgrade@odoo.com""")
self.ensure_one() self.ensure_one()
# create a new history record: # create a new history record:
+2
View File
@@ -701,6 +701,8 @@ class Lead(models.Model):
@api.model @api.model
def _get_duplicated_leads_by_emails(self, partner_id, email, include_lost=False): def _get_duplicated_leads_by_emails(self, partner_id, email, include_lost=False):
""" Search for opportunities that have the same partner and that arent done or cancelled """ """ Search for opportunities that have the same partner and that arent done or cancelled """
if not email:
return []
partner_match_domain = [] partner_match_domain = []
for email in set(email_split(email) + [email]): for email in set(email_split(email) + [email]):
partner_match_domain.append(('email_from', '=ilike', email)) partner_match_domain.append(('email_from', '=ilike', email))
+3
View File
@@ -88,6 +88,9 @@ class SaleOrder(models.Model):
def _create_delivery_line(self, carrier, price_unit): def _create_delivery_line(self, carrier, price_unit):
SaleOrderLine = self.env['sale.order.line'] SaleOrderLine = self.env['sale.order.line']
if self.partner_id:
# set delivery detail in the customer language
carrier = carrier.with_context(lang=self.partner_id.lang)
# Apply fiscal position # Apply fiscal position
taxes = carrier.product_id.taxes_id.filtered(lambda t: t.company_id.id == self.company_id.id) taxes = carrier.product_id.taxes_id.filtered(lambda t: t.company_id.id == self.company_id.id)
@@ -53,6 +53,7 @@ class HrPayslip(models.Model):
@api.multi @api.multi
def action_payslip_done(self): def action_payslip_done(self):
res = super(HrPayslip, self).action_payslip_done()
precision = self.env['decimal.precision'].precision_get('Payroll') precision = self.env['decimal.precision'].precision_get('Payroll')
for slip in self: for slip in self:
@@ -138,7 +139,7 @@ class HrPayslip(models.Model):
move = self.env['account.move'].create(move_dict) move = self.env['account.move'].create(move_dict)
slip.write({'move_id': move.id, 'date': date}) slip.write({'move_id': move.id, 'date': date})
move.post() move.post()
return super(HrPayslip, self).action_payslip_done() return res
class HrSalaryRule(models.Model): class HrSalaryRule(models.Model):
+1 -1
View File
@@ -358,7 +358,7 @@ class Escpos:
else: else:
self._raw(string) self._raw(string)
raw += S_RASTER_N raw += S_RASTER_N.encode('utf-8')
buffer = "%02X%02X%02X%02X" % (int((size[0]/size[1])/8), 0, size[1], 0) buffer = "%02X%02X%02X%02X" % (int((size[0]/size[1])/8), 0, size[1], 0)
raw += codecs.decode(buffer, 'hex') raw += codecs.decode(buffer, 'hex')
buffer = "" buffer = ""
+8 -1
View File
@@ -108,7 +108,14 @@
<td></td> <td></td>
<td></td> <td></td>
<td t-if="display_discount" groups="sale.group_discount_per_so_line"></td> <td t-if="display_discount" groups="sale.group_discount_per_so_line"></td>
<td t-att-colspan="o.company_id.country_id.code == 'IN' and 5 or 1"></td> <td t-if="len(o.tax_line_ids) > 0"></td>
<td></td>
<t t-if="o.company_id.country_id.code == 'IN'">
<td t-if="is_cgst"></td>
<td t-if="is_cgst"></td>
<td t-if="is_igst"></td>
<td t-if="is_cess"></td>
</t>
</tr> </tr>
</tbody> </tbody>
</table> </table>
+1 -1
View File
@@ -35,7 +35,7 @@ class MailThread(models.AbstractModel):
""" Override to update the parent mail statistics. The parent is found """ Override to update the parent mail statistics. The parent is found
by using the References header of the incoming message and looking for by using the References header of the incoming message and looking for
matching message_id in mail.mail.statistics. """ matching message_id in mail.mail.statistics. """
if message.get('References'): if message.get('References') and routes:
message_ids = [x.strip() for x in decode_smtp_header(message['References']).split()] message_ids = [x.strip() for x in decode_smtp_header(message['References']).split()]
self.env['mail.mail.statistics'].set_opened(mail_message_ids=message_ids) self.env['mail.mail.statistics'].set_opened(mail_message_ids=message_ids)
self.env['mail.mail.statistics'].set_replied(mail_message_ids=message_ids) self.env['mail.mail.statistics'].set_replied(mail_message_ids=message_ids)
@@ -106,7 +106,7 @@ class MailMailStats(models.Model):
def set_opened(self, mail_mail_ids=None, mail_message_ids=None): def set_opened(self, mail_mail_ids=None, mail_message_ids=None):
statistics = self._get_records(mail_mail_ids, mail_message_ids, [('opened', '=', False)]) statistics = self._get_records(mail_mail_ids, mail_message_ids, [('opened', '=', False)])
statistics.write({'opened': fields.Datetime.now()}) statistics.write({'opened': fields.Datetime.now(), 'bounced': False})
return statistics return statistics
def set_clicked(self, mail_mail_ids=None, mail_message_ids=None): def set_clicked(self, mail_mail_ids=None, mail_message_ids=None):
@@ -120,6 +120,7 @@ class MailMailStats(models.Model):
return statistics return statistics
def set_bounced(self, mail_mail_ids=None, mail_message_ids=None): def set_bounced(self, mail_mail_ids=None, mail_message_ids=None):
statistics = self._get_records(mail_mail_ids, mail_message_ids, [('bounced', '=', False)]) statistics = self._get_records(
mail_mail_ids, mail_message_ids, [('bounced', '=', False), ('opened', '=', False)])
statistics.write({'bounced': fields.Datetime.now()}) statistics.write({'bounced': fields.Datetime.now()})
return statistics return statistics
+2 -2
View File
@@ -134,7 +134,7 @@ odoo.define('payment.payment_form', function (require) {
self.displayError( self.displayError(
_t('Server Error'), _t('Server Error'),
_t("We are not able to add your payment method at the moment.") + _t("We are not able to add your payment method at the moment.") +
data.data.message message.data.message
); );
}); });
} }
@@ -179,7 +179,7 @@ odoo.define('payment.payment_form', function (require) {
self.displayError( self.displayError(
_t('Server Error'), _t('Server Error'),
_t("We are not able to redirect you to the payment form. ") + _t("We are not able to redirect you to the payment form. ") +
data.data.message message.data.message
); );
}); });
} }
+6 -5
View File
@@ -28,11 +28,12 @@ class AccountInvoice(models.Model):
purchase_line_ids = self.invoice_line_ids.mapped('purchase_line_id') purchase_line_ids = self.invoice_line_ids.mapped('purchase_line_id')
purchase_ids = self.invoice_line_ids.mapped('purchase_id').filtered(lambda r: r.order_line <= purchase_line_ids) purchase_ids = self.invoice_line_ids.mapped('purchase_id').filtered(lambda r: r.order_line <= purchase_line_ids)
result['domain'] = {'purchase_id': [ domain = [('invoice_status', '=', 'to invoice')]
('invoice_status', '=', 'to invoice'), if self.partner_id:
('partner_id', 'child_of', self.partner_id.id), domain += [('partner_id', 'child_of', self.partner_id.id)]
('id', 'not in', purchase_ids.ids), if purchase_ids:
]} domain += [('id', 'not in', purchase_ids.ids)]
result['domain'] = {'purchase_id': domain}
return result return result
def _prepare_invoice_line_from_po_line(self, line): def _prepare_invoice_line_from_po_line(self, line):
+4 -3
View File
@@ -395,10 +395,11 @@ class PurchaseOrder(models.Model):
if order.state in ('draft', 'sent', 'to approve'): if order.state in ('draft', 'sent', 'to approve'):
for order_line in order.order_line: for order_line in order.order_line:
if order_line.move_dest_ids: if order_line.move_dest_ids:
siblings_states = (order_line.move_dest_ids.mapped('move_orig_ids')).mapped('state') move_dest_ids = order_line.move_dest_ids.filtered(lambda m: m.state not in ('done', 'cancel'))
siblings_states = (move_dest_ids.mapped('move_orig_ids')).mapped('state')
if all(state in ('done', 'cancel') for state in siblings_states): if all(state in ('done', 'cancel') for state in siblings_states):
order_line.move_dest_ids.write({'procure_method': 'make_to_stock'}) move_dest_ids.write({'procure_method': 'make_to_stock'})
order_line.move_dest_ids._recompute_state() move_dest_ids._recompute_state()
for pick in order.picking_ids.filtered(lambda r: r.state != 'cancel'): for pick in order.picking_ids.filtered(lambda r: r.state != 'cancel'):
pick.action_cancel() pick.action_cancel()
+6
View File
@@ -666,6 +666,12 @@ class SaleOrder(models.Model):
'target': 'self', 'target': 'self',
'res_id': self.id, 'res_id': self.id,
} }
else:
action = self.env.ref('sale.action_quotations', False)
if action:
result = action.read()[0]
result['res_id'] = self.id
return result
return super(SaleOrder, self).get_access_action(access_uid) return super(SaleOrder, self).get_access_action(access_uid)
def get_mail_url(self): def get_mail_url(self):
-2
View File
@@ -715,8 +715,6 @@ class Picking(models.Model):
if product and product.tracking != 'none': if product and product.tracking != 'none':
if not line.lot_name and not line.lot_id: if not line.lot_name and not line.lot_id:
raise UserError(_('You need to supply a Lot/Serial number for product %s.') % product.display_name) raise UserError(_('You need to supply a Lot/Serial number for product %s.') % product.display_name)
elif line.qty_done == 0:
raise UserError(_('You cannot validate a transfer if you have not processed any quantity for %s.') % product.display_name)
if no_quantities_done: if no_quantities_done:
view = self.env.ref('stock.view_immediate_transfer') view = self.env.ref('stock.view_immediate_transfer')
+6 -7
View File
@@ -3158,7 +3158,7 @@ class StockMove(TransactionCase):
def test_immediate_validate_4(self): def test_immediate_validate_4(self):
""" In a picking with a single available tracked by lot move, clicking on validate without """ In a picking with a single available tracked by lot move, clicking on validate without
filling any quantities should open an UserError. filling any quantities should pop up the immediate transfer wizard.
""" """
partner = self.env['res.partner'].create({'name': 'Jean'}) partner = self.env['res.partner'].create({'name': 'Jean'})
lot1 = self.env['stock.production.lot'].create({ lot1 = self.env['stock.production.lot'].create({
@@ -3184,12 +3184,11 @@ class StockMove(TransactionCase):
}) })
picking.action_confirm() picking.action_confirm()
picking.action_assign() picking.action_assign()
# No quantites/lot filled, it should raise. # No quantites filled, immediate transfer wizard should pop up.
with self.assertRaises(UserError): immediate_trans_wiz_dict = picking.button_validate()
picking.button_validate() self.assertEqual(immediate_trans_wiz_dict.get('res_model'), 'stock.immediate.transfer')
picking.move_lines.move_line_ids[0].qty_done = 5.0 immediate_trans_wiz = self.env[immediate_trans_wiz_dict['res_model']].browse(immediate_trans_wiz_dict['res_id'])
# All the information are present (lots and quantities), the wizard won't be opened. immediate_trans_wiz.process()
picking.button_validate()
self.assertEqual(picking.move_lines.quantity_done, 5.0) self.assertEqual(picking.move_lines.quantity_done, 5.0)
# Check move_lines data # Check move_lines data
@@ -18,6 +18,7 @@ This module allows you to easily add extra costs on pickings and decide the spli
], ],
'data': [ 'data': [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'security/stock_landed_cost_security.xml',
'data/stock_landed_cost_data.xml', 'data/stock_landed_cost_data.xml',
'views/product_views.xml', 'views/product_views.xml',
'views/stock_landed_cost_views.xml', 'views/stock_landed_cost_views.xml',
@@ -51,6 +51,8 @@ class LandedCost(models.Model):
account_journal_id = fields.Many2one( account_journal_id = fields.Many2one(
'account.journal', 'Account Journal', 'account.journal', 'Account Journal',
required=True, states={'done': [('readonly', True)]}) required=True, states={'done': [('readonly', True)]})
company_id = fields.Many2one('res.company', string="Company",
related='account_journal_id.company_id')
@api.one @api.one
@api.depends('cost_lines.price_unit') @api.depends('cost_lines.price_unit')
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record model="ir.rule" id="stock_landed_cost_rule">
<field name="name">stock_landed_cost multi-company</field>
<field name="model_id" search="[('model','=','stock.landed.cost')]" model="ir.model"/>
<field name="global" eval="True"/>
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record>
</data>
</odoo>
@@ -949,6 +949,9 @@ var VideoWidget = MediaWidget.extend({
return {errorCode: 1}; return {errorCode: 1};
} }
if (ytMatch) {
$video.attr('src', $video.attr('src') + '&rel=0');
}
if (options.loop && (ytMatch || vimMatch)) { if (options.loop && (ytMatch || vimMatch)) {
$video.attr('src', $video.attr('src') + '&loop=1'); $video.attr('src', $video.attr('src') + '&loop=1');
} }
+1
View File
@@ -38,3 +38,4 @@ Raúl Martín raul.martin@braintec-group.com https://github.com/BT-rmartin
Silvan Wyden silvan.wyden@braintec-group.com https://github.com/BT-swyden Silvan Wyden silvan.wyden@braintec-group.com https://github.com/BT-swyden
Timka Piric Muratovic timka.piric@braintec-group.com https://github.com/BT-tpiric Timka Piric Muratovic timka.piric@braintec-group.com https://github.com/BT-tpiric
Pascal Zenklusen pascal.zenklusen@braintec-group.com https://github.com/BT-pzenklusen Pascal Zenklusen pascal.zenklusen@braintec-group.com https://github.com/BT-pzenklusen
Nadal Francisco Garcia nadal.francisco@braintec-group.com https://github.com/BT-nfrancisco
+11
View File
@@ -0,0 +1,11 @@
Italy, 2018-08-08
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,
Marco Calcagni mcalcagni@dinamicheaziendali.it https://github.com/As400it
+2 -2
View File
@@ -6,9 +6,9 @@
"base.lang_bs_BA","Bosnian / bosanski jezik","bs_BA","bs","Left-to-Right","[]",",",,"%d.%m.%Y","%H:%M:%S","True","7" "base.lang_bs_BA","Bosnian / bosanski jezik","bs_BA","bs","Left-to-Right","[]",",",,"%d.%m.%Y","%H:%M:%S","True","7"
"base.lang_bg","Bulgarian / български език","bg_BG","bg","Left-to-Right","[3,0]",",",,"%d.%m.%Y","%H,%M,%S","True","1" "base.lang_bg","Bulgarian / български език","bg_BG","bg","Left-to-Right","[3,0]",",",,"%d.%m.%Y","%H,%M,%S","True","1"
"base.lang_ca_ES","Catalan / Català","ca_ES","ca_ES","Left-to-Right","[3,0]",",",".","%d/%m/%Y","%H:%M:%S","True","1" "base.lang_ca_ES","Catalan / Català","ca_ES","ca_ES","Left-to-Right","[3,0]",",",".","%d/%m/%Y","%H:%M:%S","True","1"
"base.lang_zh_CN","Chinese (CN) / 简体中文","zh_CN","zh_CN","Left-to-Right","[3,0]",".",",","%Y年%m月%d日","%H时%M分%S秒","True","7" "base.lang_zh_CN","Chinese (Simplified) / 简体中文","zh_CN","zh_CN","Left-to-Right","[3,0]",".",",","%Y年%m月%d日","%H时%M分%S秒","True","7"
"base.lang_zh_HK","Chinese (HK)","zh_HK","zh_HK","Left-to-Right","[3,0]",".",",","%Y年%m月%d日 %A","%I時%M分%S秒","True","7" "base.lang_zh_HK","Chinese (HK)","zh_HK","zh_HK","Left-to-Right","[3,0]",".",",","%Y年%m月%d日 %A","%I時%M分%S秒","True","7"
"base.lang_zh_TW","Chinese (TW) / 正體字","zh_TW","zh_TW","Left-to-Right","[3,0]",".",",","%Y年%m月%d日","%H時%M分%S秒","True","7" "base.lang_zh_TW","Chinese (Traditional) / 正體字","zh_TW","zh_TW","Left-to-Right","[3,0]",".",",","%Y年%m月%d日","%H時%M分%S秒","True","7"
"base.lang_hr","Croatian / hrvatski jezik","hr_HR","hr","Left-to-Right","[]",",",,"%d.%m.%Y","%H:%M:%S","True","1" "base.lang_hr","Croatian / hrvatski jezik","hr_HR","hr","Left-to-Right","[]",",",,"%d.%m.%Y","%H:%M:%S","True","1"
"base.lang_cs_CZ","Czech / Čeština","cs_CZ","cs_CZ","Left-to-Right","[3,0]",","," ","%d.%m.%Y","%H:%M:%S","True","1" "base.lang_cs_CZ","Czech / Čeština","cs_CZ","cs_CZ","Left-to-Right","[3,0]",","," ","%d.%m.%Y","%H:%M:%S","True","1"
"base.lang_da_DK","Danish / Dansk","da_DK","da_DK","Left-to-Right","[3,0]",",",".","%d-%m-%Y","%H:%M:%S","True","1" "base.lang_da_DK","Danish / Dansk","da_DK","da_DK","Left-to-Right","[3,0]",",",".","%d-%m-%Y","%H:%M:%S","True","1"
1 id name code iso_code direction grouping decimal_point thousands_sep date_format time_format translatable week_start
6 base.lang_bs_BA Bosnian / bosanski jezik bs_BA bs Left-to-Right [] , %d.%m.%Y %H:%M:%S True 7
7 base.lang_bg Bulgarian / български език bg_BG bg Left-to-Right [3,0] , %d.%m.%Y %H,%M,%S True 1
8 base.lang_ca_ES Catalan / Català ca_ES ca_ES Left-to-Right [3,0] , . %d/%m/%Y %H:%M:%S True 1
9 base.lang_zh_CN Chinese (CN) / 简体中文 Chinese (Simplified) / 简体中文 zh_CN zh_CN Left-to-Right [3,0] . , %Y年%m月%d日 %H时%M分%S秒 True 7
10 base.lang_zh_HK Chinese (HK) zh_HK zh_HK Left-to-Right [3,0] . , %Y年%m月%d日 %A %I時%M分%S秒 True 7
11 base.lang_zh_TW Chinese (TW) / 正體字 Chinese (Traditional) / 正體字 zh_TW zh_TW Left-to-Right [3,0] . , %Y年%m月%d日 %H時%M分%S秒 True 7
12 base.lang_hr Croatian / hrvatski jezik hr_HR hr Left-to-Right [] , %d.%m.%Y %H:%M:%S True 1
13 base.lang_cs_CZ Czech / Čeština cs_CZ cs_CZ Left-to-Right [3,0] ,   %d.%m.%Y %H:%M:%S True 1
14 base.lang_da_DK Danish / Dansk da_DK da_DK Left-to-Right [3,0] , . %d-%m-%Y %H:%M:%S True 1
+3
View File
@@ -575,8 +575,11 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
IrDefault.set(model, field, value) IrDefault.set(model, field, value)
# group fields: modify group / implied groups # group fields: modify group / implied groups
current_settings = self.new(self.default_get(list(self.fields_get())))
with self.env.norecompute(): with self.env.norecompute():
for name, groups, implied_group in classified['group']: for name, groups, implied_group in classified['group']:
if self[name] == current_settings[name]:
continue
if self[name]: if self[name]:
groups.write({'implied_ids': [(4, implied_group.id)]}) groups.write({'implied_ids': [(4, implied_group.id)]})
else: else:
+4
View File
@@ -46,6 +46,10 @@ class RedirectWarning(Exception):
:param string button_text: text to put on the button that will trigger :param string button_text: text to put on the button that will trigger
the redirection. the redirection.
""" """
# using this RedirectWarning won't crash if used as an except_orm
@property
def name(self):
return self.args[0]
class AccessDenied(Exception): class AccessDenied(Exception):
+1 -4
View File
@@ -1148,10 +1148,7 @@ def formatLang(env, value, digits=None, grouping=True, monetary=False, dp=False,
return '' return ''
lang = env.context.get('lang') or env.user.company_id.partner_id.lang or 'en_US' lang = env.context.get('lang') or env.user.company_id.partner_id.lang or 'en_US'
lang_objs = env['res.lang'].search([('code', '=', lang)]) lang_obj = env['res.lang']._lang_get(lang)
if not lang_objs:
lang_objs = env['res.lang'].search([], limit=1)
lang_obj = lang_objs[0]
res = lang_obj.format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary) res = lang_obj.format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
+1 -1
View File
@@ -8,7 +8,7 @@ gevent==1.3.4 ; sys_platform != 'win32' and python_version >= '3.7'
greenlet==0.4.10 ; python_version < '3.7' greenlet==0.4.10 ; python_version < '3.7'
greenlet==0.4.13 ; python_version >= '3.7' greenlet==0.4.13 ; python_version >= '3.7'
html2text==2016.9.19 html2text==2016.9.19
Jinja2==2.8 Jinja2==2.8.1
lxml==3.7.1 ; sys_platform != 'win32' and python_version < '3.7' lxml==3.7.1 ; sys_platform != 'win32' and python_version < '3.7'
lxml==4.2.3 ; sys_platform != 'win32' and python_version >= '3.7' lxml==4.2.3 ; sys_platform != 'win32' and python_version >= '3.7'
lxml ; sys_platform == 'win32' lxml ; sys_platform == 'win32'