uniform model
This commit is contained in:
parent
0c46514bc5
commit
8aa1dfdc4b
10 changed files with 209 additions and 190 deletions
|
|
@ -34,6 +34,7 @@
|
||||||
],
|
],
|
||||||
"assets": {
|
"assets": {
|
||||||
"web.assets_backend": [
|
"web.assets_backend": [
|
||||||
|
# BV: Commented out the following lines to avoid errors when installing the module.
|
||||||
# "bemade_mailcow_integration/static/src/js/mailcow.js",
|
# "bemade_mailcow_integration/static/src/js/mailcow.js",
|
||||||
# "bemade_mailcow_integration/static/src/xml/mailcow_templates.xml",
|
# "bemade_mailcow_integration/static/src/xml/mailcow_templates.xml",
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
from . import sale_order
|
from . import sale_order
|
||||||
|
from . import sale_order_line
|
||||||
|
|
@ -21,157 +21,3 @@ class SaleOrder(models.Model):
|
||||||
order.margin_percent_actual = order.amount_untaxed and order.margin_actual / order.amount_untaxed
|
order.margin_percent_actual = order.amount_untaxed and order.margin_actual / order.amount_untaxed
|
||||||
|
|
||||||
|
|
||||||
class SaleOrderLine(models.Model):
|
|
||||||
_inherit = 'sale.order.line'
|
|
||||||
|
|
||||||
purchase_price_vendor = fields.Float(
|
|
||||||
compute='_compute_purchase_price_vendor',
|
|
||||||
string="Vendor Price",
|
|
||||||
groups="base.group_user",
|
|
||||||
digits='Product Price'
|
|
||||||
)
|
|
||||||
|
|
||||||
margin_percent_vendor = fields.Float(
|
|
||||||
string='Margin (%) on Vendor Price',
|
|
||||||
groups='base.group_user',
|
|
||||||
group_operator='avg',
|
|
||||||
compute='_compute_margin_vendor'
|
|
||||||
)
|
|
||||||
|
|
||||||
margin_vendor = fields.Float(
|
|
||||||
string='Margin on Vendor Price',
|
|
||||||
groups='base.group_user',
|
|
||||||
digits='Product Price',
|
|
||||||
compute='_compute_margin_vendor'
|
|
||||||
)
|
|
||||||
|
|
||||||
purchase_price_actual = fields.Float(
|
|
||||||
compute="_compute_actual_margins",
|
|
||||||
digits='Product Price',
|
|
||||||
groups="base.group_user",
|
|
||||||
string="Purchase Price"
|
|
||||||
)
|
|
||||||
|
|
||||||
margin_actual = fields.Float(
|
|
||||||
compute="_compute_actual_margins",
|
|
||||||
digits='Product Price',
|
|
||||||
groups="base.group_user",
|
|
||||||
string="Our Margin"
|
|
||||||
)
|
|
||||||
|
|
||||||
margin_percent_actual = fields.Float(
|
|
||||||
compute="_compute_actual_margins",
|
|
||||||
groups="base.group_user",
|
|
||||||
string="Our Margin (%)"
|
|
||||||
)
|
|
||||||
|
|
||||||
@api.depends(
|
|
||||||
'purchase_price',
|
|
||||||
'purchase_price_vendor',
|
|
||||||
'move_ids.product_id',
|
|
||||||
'move_ids.product_id.qty_available',
|
|
||||||
'move_ids.state',
|
|
||||||
'qty_to_deliver'
|
|
||||||
)
|
|
||||||
def _compute_actual_margins(self):
|
|
||||||
""" We want to use the margin based on average inventory valuation when the
|
|
||||||
sale order line will be completely fulfilled (or has been fulfilled) from stock.
|
|
||||||
For product not yet in stock we want to use the vendor price. We can also have
|
|
||||||
blended calculations (partly on vendor price, partly on stock valuation). This
|
|
||||||
occurs when an order has been or would be partially fulfilled from available
|
|
||||||
stock.
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
non_product_lines = self.filtered(lambda r: not r.product_id)
|
|
||||||
non_product_lines.purchase_price_actual = 0.0
|
|
||||||
non_product_lines.margin_actual = 0.0
|
|
||||||
non_product_lines.margin_percent_actual = 0.0
|
|
||||||
for line in self - non_product_lines:
|
|
||||||
stock_missing = line._determine_missing_stock()
|
|
||||||
if float_is_zero(stock_missing, precision_rounding=line.product_uom.rounding):
|
|
||||||
# everything is coming from stock, use inventory valuation
|
|
||||||
line.purchase_price_actual = line.purchase_price
|
|
||||||
elif float_compare(line.product_uom_qty, stock_missing,
|
|
||||||
precision_rounding=line.product_uom.rounding) == 0:
|
|
||||||
# everything is coming from the vendor, use vendor pricing
|
|
||||||
line.purchase_price_actual = line.purchase_price_vendor
|
|
||||||
else:
|
|
||||||
# we have a mix, use blended pricing
|
|
||||||
qty_from_stock = line.product_uom_qty - stock_missing
|
|
||||||
line.purchase_price_actual = \
|
|
||||||
(stock_missing * line.purchase_price_vendor
|
|
||||||
+ qty_from_stock * line.purchase_price) \
|
|
||||||
/ line.product_uom_qty
|
|
||||||
line.margin_actual = line.price_subtotal - (
|
|
||||||
line.purchase_price_actual * line.product_uom_qty)
|
|
||||||
line.margin_percent_actual = line.price_subtotal and line.margin_actual / line.price_subtotal
|
|
||||||
|
|
||||||
def _determine_missing_stock(self) -> float:
|
|
||||||
""" Compute how much stock is missing to meet an order line's demand. In the
|
|
||||||
case of a quotation line, available stock is checked as if the order were to be
|
|
||||||
placed immediately.
|
|
||||||
|
|
||||||
:return: The quantity missing from available stock to fulfill the line, in
|
|
||||||
the unit of measure matching self.product_uom.
|
|
||||||
"""
|
|
||||||
self.ensure_one()
|
|
||||||
is_order = self.order_id.state in ('sale', 'done')
|
|
||||||
if is_order and self.qty_to_deliver == 0:
|
|
||||||
return 0
|
|
||||||
elif is_order and self.qty_to_deliver > 0:
|
|
||||||
reserved = sum([m.reserved_availability for m in self.move_ids])
|
|
||||||
missing = self.qty_to_deliver - reserved
|
|
||||||
if float_compare(missing, 0.0,
|
|
||||||
precision_rounding=self.product_uom.rounding) == 1:
|
|
||||||
# Not enough reserved, check stock
|
|
||||||
missing = missing - self.product_id.qty_available
|
|
||||||
if float_compare(missing, 0.0,
|
|
||||||
precision_rounding=self.product_uom.rounding) == 1:
|
|
||||||
# Missing some stock to meet demand, return the quantity
|
|
||||||
return missing
|
|
||||||
else:
|
|
||||||
# Enough stock available to meet this line's demand
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
# Already have stock reserved
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
# This is a quotation, don't bother with stock reservations
|
|
||||||
missing = self.product_uom_qty - self.product_id.qty_available
|
|
||||||
if float_compare(missing, 0.0,
|
|
||||||
precision_rounding=self.product_uom.rounding) == 1:
|
|
||||||
return missing
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
@api.depends('product_id', 'product_id.seller_ids',
|
|
||||||
'product_id.seller_ids.price')
|
|
||||||
def _compute_purchase_price_vendor(self):
|
|
||||||
for line in self:
|
|
||||||
product = line.product_id
|
|
||||||
suppinfos = product.seller_ids.sorted('sequence')
|
|
||||||
if not suppinfos:
|
|
||||||
line.purchase_price_vendor = 0.0
|
|
||||||
continue
|
|
||||||
suppinfo = suppinfos[0]
|
|
||||||
purch_currency = suppinfo.currency_id
|
|
||||||
to_cur = line.currency_id or line.order_id.currency_id
|
|
||||||
line.purchase_price_vendor = purch_currency._convert(
|
|
||||||
from_amount=suppinfo.price,
|
|
||||||
to_currency=to_cur,
|
|
||||||
company=line.company_id or self.env.company,
|
|
||||||
date=line.order_id.date_order or fields.Date.today(),
|
|
||||||
round=False,
|
|
||||||
) if to_cur and suppinfo.price else suppinfo.price
|
|
||||||
|
|
||||||
@api.depends('purchase_price_vendor')
|
|
||||||
def _compute_margin_vendor(self):
|
|
||||||
for line in self:
|
|
||||||
if not line.price_unit or float_is_zero(line.price_unit):
|
|
||||||
line.margin_vendor = 0
|
|
||||||
line.margin_percent_vendor = 0
|
|
||||||
continue
|
|
||||||
unit_margin = line.price_unit - line.purchase_price_vendor
|
|
||||||
line.margin_percent_vendor = unit_margin / line.price_unit
|
|
||||||
|
|
||||||
line.margin_vendor = unit_margin * line.product_uom_qty
|
|
||||||
|
|
|
||||||
158
bemade_margin_vendor_pricelist/models/sale_order_line.py
Normal file
158
bemade_margin_vendor_pricelist/models/sale_order_line.py
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
from odoo import models, fields, api, _
|
||||||
|
from odoo.tools.float_utils import float_is_zero, float_compare
|
||||||
|
|
||||||
|
|
||||||
|
class SaleOrderLine(models.Model):
|
||||||
|
_inherit = 'sale.order.line'
|
||||||
|
|
||||||
|
purchase_price_vendor = fields.Float(
|
||||||
|
compute='_compute_purchase_price_vendor',
|
||||||
|
string="Vendor Price",
|
||||||
|
groups="base.group_user",
|
||||||
|
digits='Product Price'
|
||||||
|
)
|
||||||
|
|
||||||
|
margin_percent_vendor = fields.Float(
|
||||||
|
string='Margin (%) on Vendor Price',
|
||||||
|
groups='base.group_user',
|
||||||
|
group_operator='avg',
|
||||||
|
compute='_compute_margin_vendor'
|
||||||
|
)
|
||||||
|
|
||||||
|
margin_vendor = fields.Float(
|
||||||
|
string='Margin on Vendor Price',
|
||||||
|
groups='base.group_user',
|
||||||
|
digits='Product Price',
|
||||||
|
compute='_compute_margin_vendor'
|
||||||
|
)
|
||||||
|
|
||||||
|
purchase_price_actual = fields.Float(
|
||||||
|
compute="_compute_actual_margins",
|
||||||
|
digits='Product Price',
|
||||||
|
groups="base.group_user",
|
||||||
|
string="Purchase Price"
|
||||||
|
)
|
||||||
|
|
||||||
|
margin_actual = fields.Float(
|
||||||
|
compute="_compute_actual_margins",
|
||||||
|
digits='Product Price',
|
||||||
|
groups="base.group_user",
|
||||||
|
string="Our Margin"
|
||||||
|
)
|
||||||
|
|
||||||
|
margin_percent_actual = fields.Float(
|
||||||
|
compute="_compute_actual_margins",
|
||||||
|
groups="base.group_user",
|
||||||
|
string="Our Margin (%)"
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends(
|
||||||
|
'purchase_price',
|
||||||
|
'purchase_price_vendor',
|
||||||
|
'move_ids.product_id',
|
||||||
|
'move_ids.product_id.qty_available',
|
||||||
|
'move_ids.state',
|
||||||
|
'qty_to_deliver'
|
||||||
|
)
|
||||||
|
def _compute_actual_margins(self):
|
||||||
|
""" We want to use the margin based on average inventory valuation when the
|
||||||
|
sale order line will be completely fulfilled (or has been fulfilled) from stock.
|
||||||
|
For product not yet in stock we want to use the vendor price. We can also have
|
||||||
|
blended calculations (partly on vendor price, partly on stock valuation). This
|
||||||
|
occurs when an order has been or would be partially fulfilled from available
|
||||||
|
stock.
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
non_product_lines = self.filtered(lambda r: not r.product_id)
|
||||||
|
non_product_lines.purchase_price_actual = 0.0
|
||||||
|
non_product_lines.margin_actual = 0.0
|
||||||
|
non_product_lines.margin_percent_actual = 0.0
|
||||||
|
for line in self - non_product_lines:
|
||||||
|
stock_missing = line._determine_missing_stock()
|
||||||
|
if float_is_zero(stock_missing, precision_rounding=line.product_uom.rounding):
|
||||||
|
# everything is coming from stock, use inventory valuation
|
||||||
|
line.purchase_price_actual = line.purchase_price
|
||||||
|
elif float_compare(line.product_uom_qty, stock_missing,
|
||||||
|
precision_rounding=line.product_uom.rounding) == 0:
|
||||||
|
# everything is coming from the vendor, use vendor pricing
|
||||||
|
line.purchase_price_actual = line.purchase_price_vendor
|
||||||
|
else:
|
||||||
|
# we have a mix, use blended pricing
|
||||||
|
qty_from_stock = line.product_uom_qty - stock_missing
|
||||||
|
line.purchase_price_actual = \
|
||||||
|
(stock_missing * line.purchase_price_vendor
|
||||||
|
+ qty_from_stock * line.purchase_price) \
|
||||||
|
/ line.product_uom_qty
|
||||||
|
line.margin_actual = line.price_subtotal - (
|
||||||
|
line.purchase_price_actual * line.product_uom_qty)
|
||||||
|
line.margin_percent_actual = line.price_subtotal and line.margin_actual / line.price_subtotal
|
||||||
|
|
||||||
|
def _determine_missing_stock(self) -> float:
|
||||||
|
""" Compute how much stock is missing to meet an order line's demand. In the
|
||||||
|
case of a quotation line, available stock is checked as if the order were to be
|
||||||
|
placed immediately.
|
||||||
|
|
||||||
|
:return: The quantity missing from available stock to fulfill the line, in
|
||||||
|
the unit of measure matching self.product_uom.
|
||||||
|
"""
|
||||||
|
self.ensure_one()
|
||||||
|
is_order = self.order_id.state in ('sale', 'done')
|
||||||
|
if is_order and self.qty_to_deliver == 0:
|
||||||
|
return 0
|
||||||
|
elif is_order and self.qty_to_deliver > 0:
|
||||||
|
reserved = sum([m.reserved_availability for m in self.move_ids])
|
||||||
|
missing = self.qty_to_deliver - reserved
|
||||||
|
if float_compare(missing, 0.0,
|
||||||
|
precision_rounding=self.product_uom.rounding) == 1:
|
||||||
|
# Not enough reserved, check stock
|
||||||
|
missing = missing - self.product_id.qty_available
|
||||||
|
if float_compare(missing, 0.0,
|
||||||
|
precision_rounding=self.product_uom.rounding) == 1:
|
||||||
|
# Missing some stock to meet demand, return the quantity
|
||||||
|
return missing
|
||||||
|
else:
|
||||||
|
# Enough stock available to meet this line's demand
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
# Already have stock reserved
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
# This is a quotation, don't bother with stock reservations
|
||||||
|
missing = self.product_uom_qty - self.product_id.qty_available
|
||||||
|
if float_compare(missing, 0.0,
|
||||||
|
precision_rounding=self.product_uom.rounding) == 1:
|
||||||
|
return missing
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@api.depends('product_id', 'product_id.seller_ids',
|
||||||
|
'product_id.seller_ids.price')
|
||||||
|
def _compute_purchase_price_vendor(self):
|
||||||
|
for line in self:
|
||||||
|
product = line.product_id
|
||||||
|
suppinfos = product.seller_ids.sorted('sequence')
|
||||||
|
if not suppinfos:
|
||||||
|
line.purchase_price_vendor = 0.0
|
||||||
|
continue
|
||||||
|
suppinfo = suppinfos[0]
|
||||||
|
purch_currency = suppinfo.currency_id
|
||||||
|
to_cur = line.currency_id or line.order_id.currency_id
|
||||||
|
line.purchase_price_vendor = purch_currency._convert(
|
||||||
|
from_amount=suppinfo.price,
|
||||||
|
to_currency=to_cur,
|
||||||
|
company=line.company_id or self.env.company,
|
||||||
|
date=line.order_id.date_order or fields.Date.today(),
|
||||||
|
round=False,
|
||||||
|
) if to_cur and suppinfo.price else suppinfo.price
|
||||||
|
|
||||||
|
@api.depends('purchase_price_vendor')
|
||||||
|
def _compute_margin_vendor(self):
|
||||||
|
for line in self:
|
||||||
|
if not line.price_unit or float_is_zero(line.price_unit):
|
||||||
|
line.margin_vendor = 0
|
||||||
|
line.margin_percent_vendor = 0
|
||||||
|
continue
|
||||||
|
unit_margin = line.price_unit - line.purchase_price_vendor
|
||||||
|
line.margin_percent_vendor = unit_margin / line.price_unit
|
||||||
|
|
||||||
|
line.margin_vendor = unit_margin * line.product_uom_qty
|
||||||
|
|
@ -17,22 +17,27 @@
|
||||||
# DEALINGS IN THE SOFTWARE.
|
# DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
{
|
{
|
||||||
'name': 'bemade_multiple_billing_contacts',
|
'name': 'Multiple Billing Contacts',
|
||||||
'version': '17.0.1.0.1',
|
'version': '17.0.1.0.1',
|
||||||
'summary': 'Send invoices to multiple contacts by default.',
|
'summary': 'Send invoices to multiple contacts by default.',
|
||||||
'description': """By default, newly created invoices add all invoice addresses for the given partner as
|
'description': """
|
||||||
followers on the invoice. If billing contacts are set manually on the sales order, those billing
|
By default, newly created invoices add all invoice addresses for the given partner as
|
||||||
contacts are added as followers on the invoice instead.""",
|
followers on the invoice. If billing contacts are set manually on the sales order, those billing
|
||||||
|
contacts are added as followers on the invoice instead.
|
||||||
|
""",
|
||||||
'category': 'Invoicing Management',
|
'category': 'Invoicing Management',
|
||||||
'author': 'Bemade Inc.',
|
'author': 'Bemade Inc.',
|
||||||
'website': 'https://www.bemade.org',
|
'website': 'https://www.bemade.org',
|
||||||
'license': 'OPL-1',
|
'license': 'OPL-1',
|
||||||
'depends': ['sale',
|
'depends': [
|
||||||
'account',
|
'sale',
|
||||||
'bemade_partner_root_ancestor',
|
'account',
|
||||||
],
|
'bemade_partner_root_ancestor',
|
||||||
'data': ['views/account_move_views.xml',
|
],
|
||||||
'views/res_partner_views.xml'],
|
'data': [
|
||||||
|
'views/account_move_views.xml',
|
||||||
|
'views/res_partner_views.xml'
|
||||||
|
],
|
||||||
'demo': [],
|
'demo': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,13 @@ from odoo import models, fields, api
|
||||||
class AccountMove(models.Model):
|
class AccountMove(models.Model):
|
||||||
_inherit = 'account.move'
|
_inherit = 'account.move'
|
||||||
|
|
||||||
billing_contacts = fields.Many2many(comodel_name='res.partner',
|
billing_contacts = fields.Many2many(
|
||||||
string="Billing Contacts",
|
comodel_name='res.partner',
|
||||||
compute='_compute_billing_contacts',
|
string="Billing Contacts",
|
||||||
inverse='_inverse_billing_contacts',
|
compute='_compute_billing_contacts',
|
||||||
store=True,)
|
inverse='_inverse_billing_contacts',
|
||||||
|
store=True
|
||||||
|
)
|
||||||
|
|
||||||
@api.depends('line_ids.sale_line_ids.order_id', 'partner_id')
|
@api.depends('line_ids.sale_line_ids.order_id', 'partner_id')
|
||||||
def _compute_billing_contacts(self):
|
def _compute_billing_contacts(self):
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,17 @@ from odoo import models, fields, api, _, Command
|
||||||
class Partner(models.Model):
|
class Partner(models.Model):
|
||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
|
|
||||||
billing_contacts = fields.Many2many(string='Default Billing Contacts',
|
billing_contacts = fields.Many2many(
|
||||||
comodel_name='res.partner',
|
string='Default Billing Contacts',
|
||||||
compute='_compute_billing_contacts',
|
comodel_name='res.partner',
|
||||||
inverse='_inverse_billing_contacts')
|
compute='_compute_billing_contacts',
|
||||||
potential_billing_contacts = fields.Many2many(comodel_name='res.partner',
|
inverse='_inverse_billing_contacts'
|
||||||
compute='_compute_billing_contacts')
|
)
|
||||||
|
|
||||||
|
potential_billing_contacts = fields.Many2many(
|
||||||
|
comodel_name='res.partner',
|
||||||
|
compute='_compute_billing_contacts'
|
||||||
|
)
|
||||||
|
|
||||||
@api.depends('child_ids.type')
|
@api.depends('child_ids.type')
|
||||||
def _compute_billing_contacts(self):
|
def _compute_billing_contacts(self):
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,13 @@ from odoo import models, fields, api, _, Command
|
||||||
class SaleOrder(models.Model):
|
class SaleOrder(models.Model):
|
||||||
_inherit = 'sale.order'
|
_inherit = 'sale.order'
|
||||||
|
|
||||||
billing_contacts = fields.Many2many(comodel_name='res.partner',
|
billing_contacts = fields.Many2many(
|
||||||
string='Billing Contacts',
|
comodel_name='res.partner',
|
||||||
compute='_compute_billing_contacts',
|
string='Billing Contacts',
|
||||||
inverse='_inverse_billing_contacts',
|
compute='_compute_billing_contacts',
|
||||||
store=True)
|
inverse='_inverse_billing_contacts',
|
||||||
|
store=True
|
||||||
|
)
|
||||||
|
|
||||||
@api.depends('partner_id')
|
@api.depends('partner_id')
|
||||||
def _compute_billing_contacts(self):
|
def _compute_billing_contacts(self):
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@
|
||||||
<field name="partner_to">{{object.id}}</field>
|
<field name="partner_to">{{object.id}}</field>
|
||||||
<field name="subject">Select Your Division at {{object.company_id.name}}</field>
|
<field name="subject">Select Your Division at {{object.company_id.name}}</field>
|
||||||
<field name="body_html" type="html">
|
<field name="body_html" type="html">
|
||||||
<table border="0" cellpadding="0" cellspacing="0"
|
<table border="0" cellpadding="0" cellspacing="0"
|
||||||
style="padding-top: 16px; background-color: #F1F1F1; font-family:Verdana, Arial, sans-serif; color: #454748; width: 100%; border-collapse:separate;">
|
style="padding-top: 16px; background-color: #F1F1F1; font-family:Verdana, Arial, sans-serif; color: #454748; width: 100%; border-collapse:separate;">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<table border="0" cellpadding="0" cellspacing="0" width="590"
|
<table border="0" cellpadding="0" cellspacing="0" width="590"
|
||||||
style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;">
|
style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;">
|
||||||
<tbody>
|
<tbody>
|
||||||
<!-- HEADER -->
|
<!-- HEADER -->
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -25,8 +25,8 @@
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" style="min-width: 590px;">
|
<td align="center" style="min-width: 590px;">
|
||||||
<table border="0" cellpadding="0" cellspacing="0" width="590"
|
<table border="0" cellpadding="0" cellspacing="0" width="590"
|
||||||
style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
|
style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td valign="top" style="font-size: 13px;">
|
<td valign="top" style="font-size: 13px;">
|
||||||
|
|
@ -55,8 +55,8 @@
|
||||||
<!-- FOOTER -->
|
<!-- FOOTER -->
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" style="min-width: 590px;">
|
<td align="center" style="min-width: 590px;">
|
||||||
<table border="0" cellpadding="0" cellspacing="0" width="590"
|
<table border="0" cellpadding="0" cellspacing="0" width="590"
|
||||||
style="min-width: 590px; background-color: white; font-size: 11px; padding: 0px 8px 0px 8px; border-collapse:separate;">
|
style="min-width: 590px; background-color: white; font-size: 11px; padding: 0px 8px 0px 8px; border-collapse:separate;">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td valign="middle" align="left">
|
<td valign="middle" align="left">
|
||||||
|
|
@ -104,4 +104,3 @@
|
||||||
</record>
|
</record>
|
||||||
</data>
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue