[MERGE] forward port branch saas-11 up to 3f3c88b
This commit is contained in:
@@ -25,7 +25,8 @@ class AccountAnalyticLine(models.Model):
|
||||
partner_id = fields.Many2one('res.partner', related='account_id.partner_id', string='Partner', store=True, readonly=True)
|
||||
|
||||
def _get_analytic_amount_currency(self):
|
||||
self.analytic_amount_currency = abs(self.amount_currency) * copysign(1, self.amount)
|
||||
for line in self:
|
||||
line.analytic_amount_currency = abs(line.amount_currency) * copysign(1, line.amount)
|
||||
|
||||
@api.v8
|
||||
@api.onchange('product_id', 'product_uom_id', 'unit_amount', 'currency_id')
|
||||
|
||||
@@ -49,7 +49,7 @@ class AccountInvoice(models.Model):
|
||||
self.amount_total = self.amount_untaxed + self.amount_tax
|
||||
amount_total_company_signed = self.amount_total
|
||||
amount_untaxed_signed = self.amount_untaxed
|
||||
if self.currency_id and self.currency_id != self.company_id.currency_id:
|
||||
if self.currency_id and self.company_id and self.currency_id != self.company_id.currency_id:
|
||||
currency_id = self.currency_id.with_context(date=self.date_invoice)
|
||||
amount_total_company_signed = currency_id.compute(self.amount_total, self.company_id.currency_id)
|
||||
amount_untaxed_signed = currency_id.compute(self.amount_untaxed, self.company_id.currency_id)
|
||||
@@ -1125,7 +1125,7 @@ class AccountInvoiceLine(models.Model):
|
||||
if self.invoice_line_tax_ids:
|
||||
taxes = self.invoice_line_tax_ids.compute_all(price, currency, self.quantity, product=self.product_id, partner=self.invoice_id.partner_id)
|
||||
self.price_subtotal = price_subtotal_signed = taxes['total_excluded'] if taxes else self.quantity * price
|
||||
if self.invoice_id.currency_id and self.invoice_id.currency_id != self.invoice_id.company_id.currency_id:
|
||||
if self.invoice_id.currency_id and self.invoice_id.company_id and self.invoice_id.currency_id != self.invoice_id.company_id.currency_id:
|
||||
price_subtotal_signed = self.invoice_id.currency_id.compute(price_subtotal_signed, self.invoice_id.company_id.currency_id)
|
||||
sign = self.invoice_id.type in ['in_refund', 'out_refund'] and -1 or 1
|
||||
self.price_subtotal_signed = price_subtotal_signed * sign
|
||||
|
||||
@@ -29,24 +29,9 @@ class StripeController(http.Controller):
|
||||
""" Create a payment transaction
|
||||
|
||||
Expects the result from the user input from checkout.js popup"""
|
||||
acquirer = request.env['payment.acquirer'].browse(int(post.get('acquirer_id')))
|
||||
|
||||
sale_order_id = int(request.session.get('sale_order_id') or post.get('sale_order_id'))
|
||||
|
||||
order = request.env['sale.order'].sudo().browse(sale_order_id)
|
||||
tx = request.env['payment.transaction'].sudo().create({
|
||||
'acquirer_id': acquirer.id,
|
||||
'reference': 'STRIPE-%s' % order.id,
|
||||
'amount': float(post.get('amount')),
|
||||
'currency_id': request.env['res.currency'].search([('name', '=', post.get('currency'))], limit=1).id,
|
||||
'partner_id': request.env.user.partner_id.id,
|
||||
'sale_order_id': order.id
|
||||
})
|
||||
order.write({
|
||||
'payment_acquirer_id': acquirer.id,
|
||||
'payment_tx_id': tx.id
|
||||
})
|
||||
request.session['sale_transaction_id'] = tx.id
|
||||
tx = request.env['payment.transaction'].sudo().browse(
|
||||
int(request.session.get('sale_transaction_id') or request.session.get('website_payment_tx_id', False))
|
||||
)
|
||||
response = tx._create_stripe_charge(tokenid=post['tokenid'])
|
||||
_logger.info('Stripe: entering form_feedback with post data %s', pprint.pformat(response))
|
||||
if response:
|
||||
|
||||
@@ -29,8 +29,10 @@ class PaymentAcquirerStripe(models.Model):
|
||||
self.ensure_one()
|
||||
stripe_tx_values = dict(tx_values)
|
||||
temp_stripe_tx_values = {
|
||||
'company': self.company_id.name,
|
||||
'amount': tx_values.get('amount'),
|
||||
'currency': tx_values.get('currency') and tx_values.get('currency').name or '',
|
||||
'currency_id': tx_values.get('currency') and tx_values.get('currency').id or '',
|
||||
'address_line1': tx_values['partner_address'],
|
||||
'address_city': tx_values['partner_city'],
|
||||
'address_country': tx_values['partner_country'] and tx_values['partner_country'].name or '',
|
||||
|
||||
@@ -13,11 +13,6 @@ odoo.define('payment_stripe.stripe', function(require) {
|
||||
}
|
||||
},
|
||||
token: function(token, args) {
|
||||
var sale_order_id = $("input[name='return_url']").val().match(/quote\/([0-9]+)/);
|
||||
if (sale_order_id) {
|
||||
sale_order_id = parseInt(sale_order_id[1]);
|
||||
}
|
||||
|
||||
handler.isTokenGenerate = true;
|
||||
ajax.jsonRpc("/payment/stripe/create_charge", 'call', {
|
||||
tokenid: token.id,
|
||||
@@ -26,8 +21,7 @@ odoo.define('payment_stripe.stripe', function(require) {
|
||||
acquirer_id: $("#acquirer_stripe").val(),
|
||||
currency: $("input[name='currency']").val(),
|
||||
invoice_num: $("input[name='invoice_num']").val(),
|
||||
return_url: $("input[name='return_url']").val(),
|
||||
sale_order_id: sale_order_id,
|
||||
return_url: $("input[name='return_url']").val()
|
||||
}).done(function(data){
|
||||
handler.isTokenGenerate = false;
|
||||
window.location.href = data;
|
||||
@@ -42,27 +36,46 @@ odoo.define('payment_stripe.stripe', function(require) {
|
||||
$(this).attr('disabled','disabled');
|
||||
|
||||
var $form = $(e.currentTarget).parents('form');
|
||||
var acquirer_id = $(e.currentTarget).closest('div.oe_sale_acquirer_button,div.oe_quote_acquirer_button').data('id');
|
||||
var acquirer_id = $(e.currentTarget).closest('div.oe_sale_acquirer_button,div.oe_quote_acquirer_button,div.o_website_payment_new_payment');
|
||||
acquirer_id = acquirer_id.data('id') || acquirer_id.data('acquirer_id');
|
||||
if (! acquirer_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var so_token = $("input[name='token']").val();
|
||||
var so_id = $("input[name='return_url']").val().match(/quote\/([0-9]+)/);
|
||||
var so_id = $("input[name='return_url']").val().match(/quote\/([0-9]+)/) || undefined;
|
||||
if (so_id) {
|
||||
so_id = parseInt(so_id[1]);
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
ajax.jsonRpc('/shop/payment/transaction/' + acquirer_id, 'call', {'so_id': so_id, 'so_token': so_token}).then(function (data) {
|
||||
$form.html(data);
|
||||
handler.open({
|
||||
name: $("input[name='merchant']").val(),
|
||||
description: $("input[name='invoice_num']").val(),
|
||||
currency: $("input[name='currency']").val(),
|
||||
amount: $("input[name='amount']").val()*100
|
||||
if ($('.o_website_payment').length !== 0) {
|
||||
ajax.jsonRpc('/website_payment/transaction', 'call', {
|
||||
reference: $("input[name='invoice_num']").val(),
|
||||
amount: $("input[name='amount']").val(),
|
||||
currency_id: $("input[name='currency_id']").val(),
|
||||
acquirer_id: acquirer_id
|
||||
}).then(function (data) {
|
||||
handler.open({
|
||||
name: $("input[name='merchant']").val(),
|
||||
description: $("input[name='invoice_num']").val(),
|
||||
currency: $("input[name='currency']").val(),
|
||||
amount: $("input[name='amount']").val()*100
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
ajax.jsonRpc('/shop/payment/transaction/' + acquirer_id, 'call', {
|
||||
so_id: so_id,
|
||||
so_token: so_token
|
||||
}).then(function (data) {
|
||||
$form.html(data);
|
||||
handler.open({
|
||||
name: $("input[name='merchant']").val(),
|
||||
description: $("input[name='invoice_num']").val(),
|
||||
currency: $("input[name='currency']").val(),
|
||||
amount: $("input[name='amount']").val()*100
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<!--Order Information -->
|
||||
<input type='hidden' name='invoice_num' t-att-value='reference'/>
|
||||
<input type='hidden' name='currency' t-att-value='currency'/>
|
||||
<input type='hidden' name='currency_id' t-att-value='currency_id'/>
|
||||
<!-- Billing Information-->
|
||||
<input type='hidden' name='name' t-att-value='name'/>
|
||||
<input type='hidden' name='address_line1' t-att-value='address_line1'/>
|
||||
|
||||
@@ -598,13 +598,13 @@ class QuantPackage(models.Model):
|
||||
'product.packaging', 'Package Type', index=True,
|
||||
help="This field should be completed only if everything inside the package share the same product, otherwise it doesn't really makes sense.")
|
||||
location_id = fields.Many2one(
|
||||
'stock.location', 'Location', compute='_compute_package_info',
|
||||
'stock.location', 'Location', compute='_compute_package_info', search='_search_location',
|
||||
index=True, readonly=True)
|
||||
company_id = fields.Many2one(
|
||||
'res.company', 'Company', compute='_compute_package_info',
|
||||
'res.company', 'Company', compute='_compute_package_info', search='_search_company',
|
||||
index=True, readonly=True)
|
||||
owner_id = fields.Many2one(
|
||||
'res.partner', 'Owner', compute='_compute_package_info',
|
||||
'res.partner', 'Owner', compute='_compute_package_info', search='_search_owner',
|
||||
index=True, readonly=True)
|
||||
|
||||
@api.one
|
||||
@@ -612,11 +612,12 @@ class QuantPackage(models.Model):
|
||||
def _compute_ancestor_ids(self):
|
||||
self.ancestor_ids = self.env['stock.quant.package'].search(['id', 'parent_of', self.id]).ids
|
||||
|
||||
@api.one
|
||||
@api.multi
|
||||
@api.depends('parent_id', 'children_ids', 'quant_ids.package_id')
|
||||
def _compute_children_quant_ids(self):
|
||||
for package in self:
|
||||
package.children_quant_ids = self.env['stock.quant'].search([('package_id', 'child_of', package.id)]).ids
|
||||
if package.id:
|
||||
package.children_quant_ids = self.env['stock.quant'].search([('package_id', 'child_of', package.id)]).ids
|
||||
|
||||
@api.depends('quant_ids.package_id', 'quant_ids.location_id', 'quant_ids.company_id', 'quant_ids.owner_id', 'ancestor_ids')
|
||||
def _compute_package_info(self):
|
||||
@@ -646,6 +647,36 @@ class QuantPackage(models.Model):
|
||||
res[package.id] = name
|
||||
return res
|
||||
|
||||
def _search_location(self, operator, value):
|
||||
if value:
|
||||
packs = self.search([('quant_ids.location_id', operator, value)])
|
||||
else:
|
||||
packs = self.search([('quant_ids', operator, value)])
|
||||
if packs:
|
||||
return [('id', 'parent_of', packs.ids)]
|
||||
else:
|
||||
return [('id', '=', False)]
|
||||
|
||||
def _search_company(self, operator, value):
|
||||
if value:
|
||||
packs = self.search([('quant_ids.company_id', operator, value)])
|
||||
else:
|
||||
packs = self.search([('quant_ids', operator, value)])
|
||||
if packs:
|
||||
return [('id', 'parent_of', packs.ids)]
|
||||
else:
|
||||
return [('id', '=', False)]
|
||||
|
||||
def _search_owner(self, operator, value):
|
||||
if value:
|
||||
packs = self.search([('quant_ids.owner_id', operator, value)])
|
||||
else:
|
||||
packs = self.search([('quant_ids', operator, value)])
|
||||
if packs:
|
||||
return [('id', 'parent_of', packs.ids)]
|
||||
else:
|
||||
return [('id', '=', False)]
|
||||
|
||||
def _check_location_constraint(self):
|
||||
'''checks that all quants in a package are stored in the same location. This function cannot be used
|
||||
as a constraint because it needs to be checked on pack operations (they may not call write on the
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</group>
|
||||
<group string="Packages" groups="stock.group_tracking_lot">
|
||||
<field name="package_id" attrs="{'required': [('product_id', '=', False)]}" domain="[('location_id', '=', location_id)]" context="{'default_location_id': location_id}"/>
|
||||
<field name="result_package_id" domain="[('location_id', '=', location_dest_id)]" context="{'default_location_id': location_dest_id}"/>
|
||||
<field name="result_package_id" domain="['|', ('location_id', '=', False), ('location_id', '=', location_dest_id)]" context="{'default_location_id': location_dest_id}"/>
|
||||
</group>
|
||||
</group>
|
||||
</form>
|
||||
|
||||
@@ -121,7 +121,7 @@ odoo.define('website_sale.website_sale', function (require) {
|
||||
if ($input.data('update_change')) {
|
||||
return;
|
||||
}
|
||||
var value = parseInt($input.val(), 10);
|
||||
var value = parseInt($input.val() || 0, 10);
|
||||
var $dom = $(this).closest('tr');
|
||||
//var default_price = parseFloat($dom.find('.text-danger > span.oe_currency_value').text());
|
||||
var $dom_optional = $dom.nextUntil(':not(.optional_product.info)');
|
||||
@@ -140,7 +140,7 @@ odoo.define('website_sale.website_sale', function (require) {
|
||||
'set_qty': value
|
||||
}).then(function (data) {
|
||||
$input.data('update_change', false);
|
||||
if (value !== parseInt($input.val(), 10)) {
|
||||
if (value !== parseInt($input.val() || 0, 10)) {
|
||||
$input.trigger('change');
|
||||
return;
|
||||
}
|
||||
@@ -186,7 +186,7 @@ odoo.define('website_sale.website_sale', function (require) {
|
||||
var product_id = +$input.closest('*:has(input[name="product_id"])').find('input[name="product_id"]').val();
|
||||
var min = parseFloat($input.data("min") || 0);
|
||||
var max = parseFloat($input.data("max") || Infinity);
|
||||
var quantity = ($link.has(".fa-minus").length ? -1 : 1) + parseFloat($input.val(),10);
|
||||
var quantity = ($link.has(".fa-minus").length ? -1 : 1) + parseFloat($input.val() || 0, 10);
|
||||
// if they are more of one input for this product (eg: option modal)
|
||||
$('input[name="'+$input.attr("name")+'"]').add($input).filter(function () {
|
||||
var $prod = $(this).closest('*:has(input[name="product_id"])');
|
||||
|
||||
@@ -52,14 +52,14 @@ class _Cleaner(clean.Cleaner):
|
||||
|
||||
def __call__(self, doc):
|
||||
# perform quote detection before cleaning and class removal
|
||||
for el in doc.iter():
|
||||
for el in doc.iter(tag=etree.Element):
|
||||
self.tag_quote(el)
|
||||
|
||||
super(_Cleaner, self).__call__(doc)
|
||||
|
||||
# if we keep style attribute, sanitize them
|
||||
if not self.style:
|
||||
for el in doc.iter():
|
||||
for el in doc.iter(tag=etree.Element):
|
||||
self.parse_style(el)
|
||||
|
||||
def tag_quote(self, el):
|
||||
|
||||
Reference in New Issue
Block a user