Initial commit: Sale packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:49 +02:00
commit 14e3d26998
6469 changed files with 2479670 additions and 0 deletions

View file

@ -0,0 +1,109 @@
Odoo Point of Sale
-----------------------------
Odoo's <a href="https://www.odoo.com/app/point-of-sale-shop">Point of Sale</a>
introduces a super clean interface with no installation required that runs
online and offline on modern hardwares.
It's full integration with the company inventory and accounting, gives you real
time statistics and consolidations amongst all shops without the hassle of
integrating several applications.
Work with the hardware you already have
---------------------------------------
### In your web browser
Odoo's POS is a web application that can run on any device that can display
websites with little to no setup required.
### Touchscreen or Keyboard ?
The Point of Sale works perfectly on any kind of touch enabled device, whether
it's multi-touch tablets like an iPad or keyboardless resistive touchscreen
terminals.
### Scales and Printers
Barcode scanners and printers are supported out of the box with no setup
required. Scales, cashboxes, and other peripherals can be used with the proxy
API.
Online and Offline
------------------
### Odoo's POS stays reliable even if your connection isn't
Deploy new stores with just an internet connection: **no installation, no
specific hardware required**. It works with any **iPad, Tablet PC, laptop** or
industrial POS machine.
While an internet connection is required to start the Point of Sale, it will
stay operational even after a complete disconnection.
A super clean user interface
----------------------------
### Simple and beautiful
Say goodbye to ugly, outdated POS software and enjoy the Odoo web interface
designed for modern retailer.
### Designed for Productivity
Whether it's for a restaurant or a shop, you can activate the multiple orders
in parallel to not make your customers wait.
### Blazing fast search
Scan products, browse through hierarchical categories, or get quick information
about products with the blasting fast filter across all your products.
Integrated Inventory Management
-------------------------------
Consolidate all your Sales Teams in real time: stores, ecommerce, sales
teams. Get real time control of the inventory and accurate forecasts to manage
procurements.
A full warehouse management system at your fingertips: get information about
products availabilities, trigger procurement requests, etc.
Deliver in-store customer services
----------------------------------
Give your shopper a strong experience by integrating in-store customer
services. Handle reparations, track warantees, follow customer claims, plan
delivery orders, etc.
Invoicing & Accounting Integration
----------------------------------
Produce customer invoices in just a few clicks. Control sales and cash in real
time and use Odoo's powerful reporting to make smarter decisions to improve
your store's efficiency.
No more hassle of having to integrate softwares: get all your sales and
inventory operations automatically posted in your G/L.
Unified Data Amongst All Shops
------------------------------
Get new products, pricing strategies and promotions applied automatically to
selected stores. Work on a unified customer base. No complex interface is
required to pilot a global strategy amongst all your stores.
With Odoo as a backend, you have a system proven to be perfectly suitable for
small stores or large multinationals.
Know your customers - in store and out
--------------------------------------
Successful brands integrates all their customer relationship accross all their
channels to develop accurate customer profile and communicate with shoppers as
they make buying decisions, in store or online.
With Odoo, you get a 360° customer view, including cross-channel sales,
interaction history, profiles, and more.

View file

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
from . import controllers
from . import report
from . import wizard
from odoo import api, SUPERUSER_ID
def uninstall_hook(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
#The search domain is based on how the sequence is defined in the _get_sequence_values method in /addons/point_of_sale/models/stock_warehouse.py
env['ir.sequence'].search([('name', 'ilike', '%Picking POS%'), ('prefix', 'ilike', '%/POS/%')]).unlink()

View file

@ -0,0 +1,172 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Point of Sale',
'version': '1.0.1',
'category': 'Sales/Point of Sale',
'sequence': 40,
'summary': 'User-friendly PoS interface for shops and restaurants',
'depends': ['stock_account', 'barcodes', 'web_editor', 'digest'],
'uninstall_hook': 'uninstall_hook',
'data': [
'security/point_of_sale_security.xml',
'security/ir.model.access.csv',
'data/default_barcode_patterns.xml',
'data/digest_data.xml',
'wizard/pos_details.xml',
'wizard/pos_payment.xml',
'wizard/pos_close_session_wizard.xml',
'wizard/pos_session_check_product_wizard.xml',
'views/pos_assets_common.xml',
'views/pos_assets_index.xml',
'views/pos_assets_qunit.xml',
'views/point_of_sale_report.xml',
'views/point_of_sale_view.xml',
'views/pos_order_view.xml',
'views/pos_category_view.xml',
'views/product_view.xml',
'views/account_journal_view.xml',
'views/pos_payment_method_views.xml',
'views/pos_payment_views.xml',
'views/pos_config_view.xml',
'views/pos_bill_view.xml',
'views/pos_session_view.xml',
'views/point_of_sale_sequence.xml',
'data/point_of_sale_data.xml',
'views/pos_order_report_view.xml',
'views/account_statement_view.xml',
'views/digest_views.xml',
'views/res_partner_view.xml',
'views/report_userlabel.xml',
'views/report_saledetails.xml',
'views/point_of_sale_dashboard.xml',
'views/report_invoice.xml',
'views/res_config_settings_views.xml',
'views/pos_ticket_view.xml',
],
'demo': [
'data/point_of_sale_demo.xml',
],
'installable': True,
'application': True,
'website': 'https://www.odoo.com/app/point-of-sale-shop',
'assets': {
## In general, you DON'T NEED to declare new assets here, just put the files in the proper directory.
## NOTABLE EXCEPTION: List the new .css files in the `point_of_sale.assets` bundle taking into consideration
## the order of the .css files.
##
## 1. When defining new component, put the .js files in `point_of_sale/static/src/js/`
## and the corresponding .xml files in `point_of_sale/static/src/xml/`
## * POS is setup to automatically include the .xml and `.js` files in `point_of_sale.assets`.
## 2. When adding new tour tests, put the .js files in `point_of_sale/static/tests/tours/`.
## 3. When adding new qunit tests, put the .js files in `point_of_sale/static/tests/unit/`.
##
## If your use case doesn't fit anything above, you might need to properly understand each "asset bundle"
## defined here and check how they are used in the following "index templates":
## 1. point_of_sale.index
## -> This is the POS UI, accessible by opening a session.
## 2. point_of_sale.qunit_suite
## -> This is the unit test, accessible by clicking the "Run Point of Sale JS Tests" button
## in the "debug" button from the backend interface.
#####################################
## Augmentation of existing assets ##
#####################################
'web.assets_backend': [
'point_of_sale/static/src/scss/pos_dashboard.scss',
'point_of_sale/static/src/backend/tours/point_of_sale.js',
'point_of_sale/static/src/backend/debug_manager.js',
],
'web.assets_tests': [
'point_of_sale/static/tests/tours/**/*',
],
####################################################
## Exclusive POS Assets 1: For running the POS UI ##
####################################################
'point_of_sale.pos_assets_backend_style': [
"web/static/src/core/ui/**/*.scss",
],
# TODO: We need to control this asset bundle.
# We can reduce the size of loaded assets in POS UI by selectively
# loading the `web` assets. We should only include what POS needs.
'point_of_sale.pos_assets_backend': [
('include', 'web.assets_backend'),
('remove', 'web/static/src/core/errors/error_handlers.js'),
('remove', 'web/static/src/legacy/legacy_rpc_error_handler.js'),
],
# This bundle includes the main pos assets.
'point_of_sale.assets': [
'point_of_sale/static/src/scss/pos_variables_extra.scss',
('include', 'web._assets_helpers'),
('include', 'web._assets_backend_helpers'),
('include', 'web._assets_primary_variables'),
'web/static/lib/bootstrap/scss/_functions.scss',
'web/static/lib/bootstrap/scss/_variables.scss',
'web/static/fonts/fonts.scss',
'web/static/src/libs/fontawesome/css/font-awesome.css',
'web/static/lib/daterangepicker/daterangepicker.css',
'point_of_sale/static/src/scss/pos.scss',
'point_of_sale/static/src/css/pos_receipts.css',
'point_of_sale/static/src/css/popups/product_info_popup.css',
'point_of_sale/static/src/css/popups/common.css',
'point_of_sale/static/src/css/popups/cash_opening_popup.css',
'point_of_sale/static/src/css/popups/closing_pos_popup.css',
'point_of_sale/static/src/css/popups/money_details_popup.css',
'web/static/src/legacy/scss/fontawesome_overridden.scss',
# Here includes the lib and POS UI assets.
'point_of_sale/static/lib/**/*.js',
'web_editor/static/lib/html2canvas.js',
'point_of_sale/static/src/js/**/*.js',
'web/static/lib/zxing-library/zxing-library.js',
'point_of_sale/static/src/xml/**/*.xml',
],
# This bundle contains the code responsible for starting the POS UI.
# It is practically the entry point.
'point_of_sale.assets_backend_prod_only': [
'point_of_sale/static/src/entry/chrome_adapter.js',
'point_of_sale/static/src/entry/main.js',
'web/static/src/start.js',
'web/static/src/legacy/legacy_setup.js',
],
#########################################################
## Exclusive POS Assets 2: For running the QUnit tests ##
#########################################################
# This bundle includes the helper assets for the unit testing.
'point_of_sale.tests_assets': [
'web/static/lib/qunit/qunit-2.9.1.css',
'web/static/lib/qunit/qunit-2.9.1.js',
'web/static/tests/legacy/helpers/**/*',
('remove', 'web/static/tests/legacy/helpers/test_utils_tests.js'),
'web/static/tests/legacy/legacy_setup.js',
'web/static/tests/helpers/**/*.js',
'web/static/tests/qunit.js',
'web/static/tests/main.js',
'web/static/tests/setup.js',
# These 2 lines below are taken from web.assets_frontend
# They're required for the web.frontend_legacy to work properly
# It is expected to add other lines coming from the web.assets_frontend
# if we need to add more and more legacy stuff that would require other scss or js.
('include', 'web._assets_helpers'),
'web/static/src/scss/pre_variables.scss',
'web/static/lib/bootstrap/scss/_variables.scss',
('include', 'web.frontend_legacy'),
],
# This bundle includes the unit tests.
'point_of_sale.qunit_suite_tests': [
'point_of_sale/static/tests/unit/**/*',
],
},
'license': 'LGPL-3',
}

View file

@ -0,0 +1 @@
from . import main

View file

@ -0,0 +1,218 @@
# -*- coding: utf-8 -*-
import logging
from odoo import http, _
from odoo.http import request
from odoo.osv.expression import AND
from odoo.tools import format_amount
from odoo.addons.account.controllers.portal import PortalAccount
_logger = logging.getLogger(__name__)
class PosController(PortalAccount):
@http.route(['/pos/web', '/pos/ui'], type='http', auth='user')
def pos_web(self, config_id=False, **k):
"""Open a pos session for the given config.
The right pos session will be selected to open, if non is open yet a new session will be created.
/pos/ui and /pos/web both can be used to acces the POS. On the SaaS,
/pos/ui uses HTTPS while /pos/web uses HTTP.
:param debug: The debug mode to load the session in.
:type debug: str.
:param config_id: id of the config that has to be loaded.
:type config_id: str.
:returns: object -- The rendered pos session.
"""
is_internal_user = request.env.user.has_group('base.group_user')
if not is_internal_user:
return request.not_found()
domain = [
('state', 'in', ['opening_control', 'opened']),
('user_id', '=', request.session.uid),
('rescue', '=', False)
]
if config_id:
domain = AND([domain,[('config_id', '=', int(config_id))]])
pos_config = request.env['pos.config'].sudo().browse(int(config_id))
pos_session = request.env['pos.session'].sudo().search(domain, limit=1)
# The same POS session can be opened by a different user => search without restricting to
# current user. Note: the config must be explicitly given to avoid fallbacking on a random
# session.
if not pos_session and config_id:
domain = [
('state', 'in', ['opening_control', 'opened']),
('rescue', '=', False),
('config_id', '=', int(config_id)),
]
pos_session = request.env['pos.session'].sudo().search(domain, limit=1)
if not pos_session or config_id and not pos_config.active:
return request.redirect('/web#action=point_of_sale.action_client_pos_menu')
# The POS only work in one company, so we enforce the one of the session in the context
company = pos_session.company_id
session_info = request.env['ir.http'].session_info()
session_info['user_context']['allowed_company_ids'] = company.ids
session_info['user_companies'] = {'current_company': company.id, 'allowed_companies': {company.id: session_info['user_companies']['allowed_companies'][company.id]}}
context = {
'session_info': session_info,
'login_number': pos_session.login(),
'pos_session_id': pos_session.id,
}
response = request.render('point_of_sale.index', context)
response.headers['Cache-Control'] = 'no-store'
return response
@http.route('/pos/ui/tests', type='http', auth="user")
def test_suite(self, mod=None, **kwargs):
domain = [
('state', '=', 'opened'),
('user_id', '=', request.session.uid),
('rescue', '=', False)
]
pos_session = request.env['pos.session'].sudo().search(domain, limit=1)
session_info = request.env['ir.http'].session_info()
session_info['user_context']['allowed_company_ids'] = pos_session.company_id.ids
context = {
'session_info': session_info,
'pos_session_id': pos_session.id,
}
return request.render('point_of_sale.qunit_suite', qcontext=context)
@http.route('/pos/sale_details_report', type='http', auth='user')
def print_sale_details(self, date_start=False, date_stop=False, **kw):
r = request.env['report.point_of_sale.report_saledetails']
pdf, _ = request.env['ir.actions.report'].with_context(date_start=date_start, date_stop=date_stop)._render_qweb_pdf('point_of_sale.sale_details_report', r)
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
return request.make_response(pdf, headers=pdfhttpheaders)
@http.route(['/pos/ticket/validate'], type='http', auth="public", website=True, sitemap=False)
def show_ticket_validation_screen(self, access_token='', **kwargs):
def _parse_additional_values(fields, prefix, kwargs):
""" Parse the values in the kwargs by extracting the ones matching the given fields name.
:return a dict with the parsed value and the field name as key, and another on with the prefix to
re-render the form with previous values if needed.
"""
res, res_prefixed = {}, {}
for field in fields:
key = prefix + field.name
if key in kwargs:
val = kwargs.pop(key)
res[field.name] = val
res_prefixed[key] = val
return res, res_prefixed
# If the route is called directly, return a 404
if not access_token:
return request.not_found()
# Get the order using the access token. We can't use the id in the route because we may not have it yet when the QR code is generated.
pos_order = request.env['pos.order'].sudo().search([('access_token', '=', access_token)])
if not pos_order:
return request.not_found()
# If the order was already invoiced, return the invoice directly by forcing the access token so that the non-connected user can see it.
if pos_order.account_move and pos_order.account_move.is_sale_document():
return request.redirect('/my/invoices/%s?access_token=%s' % (pos_order.account_move.id, pos_order.account_move._portal_ensure_token()))
# Get the optional extra fields that could be required for a localisation.
pos_order_country = pos_order.company_id.account_fiscal_country_id
additional_partner_fields = request.env['res.partner'].get_partner_localisation_fields_required_to_invoice(pos_order_country)
additional_invoice_fields = request.env['account.move'].get_invoice_localisation_fields_required_to_invoice(pos_order_country)
user_is_connected = not request.env.user._is_public()
# Validate the form by ensuring required fields are filled and the VAT is correct.
form_values = {'error': {}, 'error_message': {}, 'extra_field_values': {}}
if kwargs and request.httprequest.method == 'POST':
form_values.update(kwargs)
# Extract the additional fields values from the kwargs now as they can't be there when validating the 'regular' partner form.
partner_values, prefixed_partner_values = _parse_additional_values(additional_partner_fields, 'partner_', kwargs)
form_values['extra_field_values'].update(prefixed_partner_values)
# Do the same for invoice values, separately as they are only needed for the invoice creation.
invoice_values, prefixed_invoice_values = _parse_additional_values(additional_invoice_fields, 'invoice_', kwargs)
form_values['extra_field_values'].update(prefixed_invoice_values)
# Check the basic form fields if the user is not connected as we will need these information to create the new user.
if not user_is_connected:
error, error_message = self.details_form_validate(kwargs, partner_creation=True)
else:
# Check that the billing information of the user are filled.
error, error_message = {}, []
partner = request.env.user.partner_id
for field in self.MANDATORY_BILLING_FIELDS:
if not partner[field]:
error[field] = 'error'
error_message.append(_('The %s must be filled in your details.', request.env['ir.model.fields']._get('res.partner', field).field_description))
# Check that the "optional" additional fields are filled.
error, error_message = self.extra_details_form_validate(partner_values, additional_partner_fields, error, error_message)
error, error_message = self.extra_details_form_validate(invoice_values, additional_invoice_fields, error, error_message)
if not error:
return self._get_invoice(partner_values, invoice_values, pos_order, additional_invoice_fields, kwargs)
else:
form_values.update({'error': error, 'error_message': error_message})
elif user_is_connected:
return self._get_invoice({}, {}, pos_order, additional_invoice_fields, kwargs)
# Most of the time, the country of the customer will be the same as the order. We can prefill it by default with the country of the company.
if 'country_id' not in form_values:
form_values['country_id'] = pos_order_country.id
partner = request.env['res.partner']
# Prefill the customer extra values if there is any and an user is connected
partner = (user_is_connected and request.env.user.partner_id) or pos_order.partner_id
if partner:
if additional_partner_fields:
form_values['extra_field_values'] = {'partner_' + field.name: partner[field.name] for field in additional_partner_fields if field.name not in form_values['extra_field_values']}
# This is just to ensure that the user went and filled its information at least once.
# Another more thorough check is done upon posting the form.
if not partner.country_id or not partner.street:
form_values['partner_address'] = False
else:
form_values['partner_address'] = partner._display_address()
return request.render("point_of_sale.ticket_validation_screen", {
'partner': partner,
'address_url': f'/my/account?redirect=/pos/ticket/validate?access_token={access_token}',
'user_is_connected': user_is_connected,
'format_amount': format_amount,
'env': request.env,
'countries': request.env['res.country'].sudo().search([]),
'states': request.env['res.country.state'].sudo().search([]),
'partner_can_edit_vat': True,
'pos_order': pos_order,
'invoice_required_fields': additional_invoice_fields,
'partner_required_fields': additional_partner_fields,
'access_token': access_token,
**form_values,
})
def _get_invoice(self, partner_values, invoice_values, pos_order, additional_invoice_fields, kwargs):
# If the user is not connected, then we will simply create a new partner with the form values.
# Matching with existing partner was tried, but we then can't update the values, and it would force the user to use the ones from the first invoicing.
if request.env.user._is_public() and not pos_order.partner_id.id:
partner_values.update({key: kwargs[key] for key in self.MANDATORY_BILLING_FIELDS})
partner_values.update({key: kwargs[key] for key in self.OPTIONAL_BILLING_FIELDS if key in kwargs})
for field in {'country_id', 'state_id'} & set(partner_values.keys()):
try:
partner_values[field] = int(partner_values[field])
except Exception:
partner_values[field] = False
partner_values.update({'zip': partner_values.pop('zipcode', '')})
partner = request.env['res.partner'].sudo().create(partner_values) # In this case, partner_values contains the whole partner info form.
# If the user is connected, then we can update if needed its fields with the additional localized fields if any, then proceed.
else:
partner = pos_order.partner_id or (not request.env.user._is_public() and request.env.user.partner_id)
partner.write(partner_values) # In this case, partner_values only contains the additional fields that can be updated.
pos_order.partner_id = partner
# Get the required fields for the invoice and add them to the context as default values.
with_context = {}
for field in additional_invoice_fields:
with_context.update({f'default_{field.name}': invoice_values.get(field.name)})
# Allowing default values for moves is important for some localizations that would need specific fields to be set on the invoice, such as Mexico.
pos_order.with_context(with_context).action_pos_order_invoice()
return request.redirect('/my/invoices/%s?access_token=%s' % (pos_order.account_move.id, pos_order.account_move._portal_ensure_token()))

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record id="barcode_rule_cashier" model="barcode.rule">
<field name="name">Cashier Barcodes</field>
<field name="barcode_nomenclature_id" ref="barcodes.default_barcode_nomenclature"/>
<field name="sequence">50</field>
<field name="type">cashier</field>
<field name="encoding">any</field>
<field name="pattern">041</field>
</record>
<record id="barcode_rule_client" model="barcode.rule">
<field name="name">Customer Barcodes</field>
<field name="barcode_nomenclature_id" ref="barcodes.default_barcode_nomenclature"/>
<field name="sequence">40</field>
<field name="type">client</field>
<field name="encoding">any</field>
<field name="pattern">042</field>
</record>
<record id="barcode_rule_discount" model="barcode.rule">
<field name="name">Discount Barcodes</field>
<field name="barcode_nomenclature_id" ref="barcodes.default_barcode_nomenclature"/>
<field name="sequence">20</field>
<field name="type">discount</field>
<field name="encoding">any</field>
<field name="pattern">22{NN}</field>
</record>
<record id="barcode_rule_price_two_dec" model="barcode.rule">
<field name="name">Price Barcodes 2 Decimals</field>
<field name="barcode_nomenclature_id" ref="barcodes.default_barcode_nomenclature"/>
<field name="sequence">14</field>
<field name="type">price</field>
<field name="encoding">ean13</field>
<field name="pattern">23.....{NNNDD}</field>
</record>
</odoo>

View file

@ -0,0 +1,8 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<data noupdate="1">
<record id="digest.digest_digest_default" model="digest.digest">
<field name="kpi_pos_total">True</field>
</record>
</data>
</odoo>

View file

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<function model="stock.warehouse" name="_create_missing_pos_picking_types"/>
</data>
<data noupdate="1">
<!-- After closing the PoS, open the dashboard menu -->
<record id="action_client_pos_menu" model="ir.actions.client">
<field name="name">Reload POS Menu</field>
<field name="tag">reload</field>
<field name="params" eval="{'menu_id': ref('menu_point_root')}"/>
</record>
<record id="product_category_pos" model="product.category">
<field name="parent_id" ref="product.product_category_1"/>
<field name="name">PoS</field>
</record>
<record id="product_product_tip" model="product.product">
<field name="name">Tips</field>
<field name="categ_id" ref="point_of_sale.product_category_pos"/>
<field name="default_code">TIPS</field>
<field name="weight">0.01</field>
<field name="available_in_pos">False</field>
<field name="taxes_id" eval="[(5,)]"/>
</record>
<record model="pos.config" id="pos_config_main" forcecreate="0">
<field name="name">Shop</field>
</record>
<record id="product_product_consumable" model="product.product">
<field name="name">Discount</field>
<field name="available_in_pos">False</field>
<field name="standard_price">0.00</field>
<field name="list_price">0.00</field>
<field name="weight">0.00</field>
<field name="type">consu</field>
<field name="categ_id" ref="point_of_sale.product_category_pos"/>
<field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="default_code">DISC</field>
<field name="purchase_ok">False</field>
</record>
<record id="uom.product_uom_categ_unit" model="uom.category">
<field name="is_pos_groupable">True</field>
</record>
<record model="pos.bill" id="0_01" forcecreate="0">
<field name="name">0.01</field>
<field name="value">0.01</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="0_02" forcecreate="0">
<field name="name">0.02</field>
<field name="value">0.02</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="0_05" forcecreate="0">
<field name="name">0.05</field>
<field name="value">0.05</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="0_10" forcecreate="0">
<field name="name">0.10</field>
<field name="value">0.10</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="0_20" forcecreate="0">
<field name="name">0.20</field>
<field name="value">0.20</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="0_25" forcecreate="0">
<field name="name">0.25</field>
<field name="value">0.25</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="0_50" forcecreate="0">
<field name="name">0.50</field>
<field name="value">0.50</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="1_00" forcecreate="0">
<field name="name">1.00</field>
<field name="value">1.00</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="2_00" forcecreate="0">
<field name="name">2.00</field>
<field name="value">2.00</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="5_00" forcecreate="0">
<field name="name">5.00</field>
<field name="value">5.00</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="10_00" forcecreate="0">
<field name="name">10.00</field>
<field name="value">10.00</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="20_00" forcecreate="0">
<field name="name">20.00</field>
<field name="value">20.00</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="50_00" forcecreate="0">
<field name="name">50.00</field>
<field name="value">50.00</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="100_00" forcecreate="0">
<field name="name">100.00</field>
<field name="value">100.00</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<record model="pos.bill" id="200_00" forcecreate="0">
<field name="name">200.00</field>
<field name="value">200.00</field>
<field name="pos_config_ids" eval="[(6, False, [ref('point_of_sale.pos_config_main')])]"/>
</record>
<function model="pos.config" name="post_install_pos_localisation" />
</data>
</odoo>

View file

@ -0,0 +1,375 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Partners with Barcodes -->
<record id='base.res_partner_1' model='res.partner'> <field name='barcode'>0420100000005</field> </record>
<record id='base.res_partner_2' model='res.partner'> <field name='barcode'>0420200000004</field> </record>
<record id='base.res_partner_3' model='res.partner'> <field name='barcode'>0420300000003</field> </record>
<record id='base.res_partner_4' model='res.partner'> <field name='barcode'>0420400000002</field> </record>
<record id='base.res_partner_4' model='res.partner'> <field name='barcode'>0420700000009</field> </record>
<record id='base.res_partner_10' model='res.partner'> <field name='barcode'>0421000000003</field> </record>
<record id='base.res_partner_12' model='res.partner'> <field name='barcode'>0420800000008</field> </record>
<record id='base.res_partner_18' model='res.partner'> <field name='barcode'>0421800000005</field> </record>
<record id="base.user_root" model="res.users">
<field name="barcode">0410100000006</field>
<field name="groups_id" eval="[(4,ref('group_pos_manager'))]"/>
</record>
<record id="base.user_demo" model="res.users">
<field name="groups_id" eval="[(4, ref('group_pos_user'))]"/>
</record>
<!-- Resource: pos.category -->
<record id="pos_category_miscellaneous" model="pos.category">
<field name="name">Miscellaneous</field>
</record>
<record id="pos_category_desks" model="pos.category">
<field name="name">Desks</field>
</record>
<record id="pos_category_chairs" model="pos.category">
<field name="name">Chairs</field>
</record>
<record model="pos.config" id="pos_config_main">
<field name="iface_start_categ_id" ref="pos_category_chairs"/>
<field name="start_category">True</field>
</record>
<!-- Resource: product.product -->
<record id="stock.product_cable_management_box" model="product.product">
<field name="pos_categ_id" ref="point_of_sale.pos_category_miscellaneous"/>
</record>
<record id="wall_shelf" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">1.98</field>
<field name="name">Wall Shelf Unit</field>
<field name="default_code">FURN_0009</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="to_weight">True</field>
<field name="barcode">2100002000003</field>
<field name="taxes_id" eval='[(5,)]'/>
<field name="categ_id" ref="product.product_category_5"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/wall_shelf_unit.png"/>
</record>
<record id="small_shelf" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">2.83</field>
<field name="name">Small Shelf</field>
<field name="default_code">FURN_0008</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="taxes_id" eval='[(5,)]'/>
<field name="categ_id" ref="product.product_category_5"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="to_weight">True</field>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/small_shelf.png"/>
</record>
<record id="letter_tray" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">4.80</field>
<field name="name">Letter Tray</field>
<field name="default_code">FURN_0004</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="to_weight">True</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/letter_tray.png"/>
</record>
<record id="desk_organizer" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">5.10</field>
<field name="name">Desk Organizer</field>
<field name="default_code">FURN_0001</field>
<field name="to_weight">True</field>
<field name="barcode">2300001000008</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/desk_organizer.png"/>
<field name="taxes_id" eval='[(5,)]'/> <!-- no taxes -->
</record>
<function model="ir.model.data" name="_update_xmlids">
<value model="base" eval="[{
'xml_id': 'point_of_sale.desk_organizer_product_template',
'record': obj().env.ref('point_of_sale.desk_organizer').product_tmpl_id,
'noupdate': True,
}]"/>
</function>
<record id="size_attribute" model="product.attribute">
<field name="name">Size</field>
<field name="sequence">30</field>
<field name="display_type">radio</field>
<field name="create_variant">no_variant</field>
</record>
<record id="size_attribute_s" model="product.attribute.value">
<field name="name">S</field>
<field name="sequence">1</field>
<field name="attribute_id" ref="size_attribute"/>
</record>
<record id="size_attribute_m" model="product.attribute.value">
<field name="name">M</field>
<field name="sequence">2</field>
<field name="attribute_id" ref="size_attribute"/>
</record>
<record id="size_attribute_l" model="product.attribute.value">
<field name="name">L</field>
<field name="sequence">3</field>
<field name="attribute_id" ref="size_attribute"/>
</record>
<record id="desk_organizer_size" model="product.template.attribute.line">
<field name="product_tmpl_id" ref="point_of_sale.desk_organizer_product_template"/>
<field name="attribute_id" ref="size_attribute"/>
<field name="value_ids" eval="[(6, 0, [ref('size_attribute_s'), ref('size_attribute_m'), ref('size_attribute_l')])]"/>
</record>
<record id="fabric_attribute" model="product.attribute">
<field name="name">Fabric</field>
<field name="sequence">40</field>
<field name="display_type">select</field>
<field name="create_variant">no_variant</field>
</record>
<record id="fabric_attribute_plastic" model="product.attribute.value">
<field name="name">Plastic</field>
<field name="sequence">1</field>
<field name="attribute_id" ref="fabric_attribute"/>
</record>
<record id="fabric_attribute_leather" model="product.attribute.value">
<field name="name">Leather</field>
<field name="sequence">2</field>
<field name="attribute_id" ref="fabric_attribute"/>
</record>
<record id="fabric_attribute_custom" model="product.attribute.value">
<field name="name">Custom</field>
<field name="sequence">3</field>
<field name="attribute_id" ref="fabric_attribute"/>
<field name="is_custom">True</field>
</record>
<record id="desk_organizer_fabric" model="product.template.attribute.line">
<field name="product_tmpl_id" ref="point_of_sale.desk_organizer_product_template"/>
<field name="attribute_id" ref="fabric_attribute"/>
<field name="value_ids" eval="[(6, 0, [ref('fabric_attribute_plastic'), ref('fabric_attribute_leather'), ref('fabric_attribute_custom')])]"/>
</record>
<record id="magnetic_board" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">1.98</field>
<field name="name">Magnetic Board</field>
<field name="default_code">FURN_0005</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="barcode">2301000000006</field>
<field name="to_weight">True</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/magnetic_board.png"/>
</record>
<record id="monitor_stand" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">3.19</field>
<field name="name">Monitor Stand</field>
<field name="default_code">FURN_0006</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="to_weight">True</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/monitor_stand.png"/>
</record>
<record id="desk_pad" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">1.98</field>
<field name="name">Desk Pad</field>
<field name="default_code">FURN_0002</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="to_weight">True</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/desk_pad.png"/>
</record>
<record id="whiteboard" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">1.70</field>
<field name="name">Whiteboard</field>
<field name="to_weight">True</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/whiteboard.png"/>
</record>
<record id="led_lamp" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">0.90</field>
<field name="name">LED Lamp</field>
<field name="default_code">FURN_0003</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="to_weight">True</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/led_lamp.png"/>
</record>
<record id="newspaper_rack" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">1.28</field>
<field name="name">Newspaper Rack</field>
<field name="default_code">FURN_0007</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="to_weight">True</field>
<field name="barcode">2100001000004</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/newspaper_stand.png"/>
</record>
<record id="whiteboard_pen" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">1.20</field>
<field name="name">Whiteboard Pen</field>
<field name="weight">0.01</field>
<field name="default_code">CONS_0001</field>
<field name="to_weight">True</field>
<field name="categ_id" ref="product.product_category_consumable"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/whiteboard_pen.png"/>
</record>
<record id="product.product_product_1" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_2" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_delivery_01" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_chairs"/>
</record>
<record id="product.product_delivery_02" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_order_01" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_3" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_desks"/>
</record>
<record id="product.product_product_4_product_template" model="product.template">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_desks"/>
</record>
<record id="product.product_product_5" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_desks"/>
</record>
<record id="product.product_product_6" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_7" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_8" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_desks"/>
</record>
<record id="product.product_product_9" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_10" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_11" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_chairs"/>
</record>
<record id="product.product_product_11b" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_chairs"/>
</record>
<record id="product.product_product_12" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_chairs"/>
</record>
<record id="product.product_product_13" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_desks"/>
</record>
<record id="product.product_product_16" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_20" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_22" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_24" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_25" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.product_product_27" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.consu_delivery_03" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_desks"/>
</record>
<record id="product.consu_delivery_02" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
<record id="product.consu_delivery_01" model="product.product">
<field name="available_in_pos" eval="True"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
</record>
</odoo>

View file

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="pos_category_furniture" model="pos.category">
<field name="name">Office furniture</field>
</record>
<record id="pos_category_miscellaneous" model="pos.category">
<field name="name">Miscellaneous</field>
</record>
<record id="wall_shelf" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">1.98</field>
<field name="name">Wall Shelf Unit</field>
<field name="default_code">FURN_0009</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="to_weight">True</field>
<field name="barcode">2100002000003</field>
<field name="taxes_id" eval='[(5,)]'/>
<field name="categ_id" ref="product.product_category_1"/>
<field name="pos_categ_id" ref="pos_category_furniture"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/wall_shelf_unit.png"/>
</record>
<record id="small_shelf" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">2.83</field>
<field name="name">Small Shelf</field>
<field name="default_code">FURN_0008</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="taxes_id" eval='[(5,)]'/>
<field name="categ_id" ref="product.product_category_1"/>
<field name="pos_categ_id" ref="pos_category_furniture"/>
<field name="to_weight">True</field>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/small_shelf.png"/>
</record>
<record id="monitor_stand" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">3.19</field>
<field name="name">Monitor Stand</field>
<field name="default_code">FURN_0006</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="to_weight">True</field>
<field name="categ_id" ref="product.product_category_1"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/monitor_stand.png"/>
</record>
<record id="desk_organizer" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">5.10</field>
<field name="name">Desk Organizer</field>
<field name="default_code">FURN_0001</field>
<field name="to_weight">True</field>
<field name="barcode">2300001000008</field>
<field name="type">product</field>
<field name="weight">0.01</field>
<field name="categ_id" ref="product.product_category_1"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/desk_organizer.png"/>
</record>
<record id="whiteboard_pen" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">1.20</field>
<field name="name">Whiteboard Pen</field>
<field name="weight">0.01</field>
<field name="default_code">CONS_0001</field>
<field name="to_weight">True</field>
<field name="categ_id" ref="product.product_category_1"/>
<field name="pos_categ_id" ref="pos_category_miscellaneous"/>
<field name="uom_id" ref="uom.product_uom_unit" />
<field name="uom_po_id" ref="uom.product_uom_unit" />
<field name="image_1920" type="base64" file="point_of_sale/static/img/whiteboard_pen.png"/>
</record>
</odoo>

View file

@ -0,0 +1,525 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="barcode_test_sheet.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.86706515"
inkscape:cx="381.55817"
inkscape:cy="505.31292"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1855"
inkscape:window-height="1176"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g4158"
transform="matrix(0.92675002,0,0,0.92675002,27.597551,38.360312)">
<text
sodipodi:linespacing="125%"
id="text2985"
y="72.12545"
x="140.86679"
style="font-size:46.51613998px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="72.12545"
x="140.86679"
id="tspan2987"
sodipodi:role="line">BARCODE TEST SHEET</tspan></text>
<g
transform="translate(0,-5.3405762e-5)"
id="g3347">
<image
y="124.14642"
x="388.17426"
id="image3083"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAADqUlEQVR4 nO3a226jMABFUYjy/7/MPCChDBfHARM4zVpP1dQY4u66JEw/DEO3S9/3XdeNh79+vRwz2hr5OmZr 5JH5t0YuX0X51W0dW3PNNa9xOWf5au8wsrxu9Ud95HHkYPg+yRJGsoSRLGEkSxjJEkayhJEsYSRL GMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJ EkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJG soSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKE kSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEs YSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEk SxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxh+mEY dh7Z913XjYe/fv3LrMlS8zWxyxJGsjuNGwbf91z911Z/1GY/18oJ689+cOTb7LZmPtJr/ZrcfOTu 1SucseaQlV221f6xnKdm5vqznzHy1Nn6vq9fk5SRrYzzry7RzHyXbd7r9HszXVP9b3bN/EdGlq/k 0y250uu0W2tSv3oXjvxo9d4ahmE6b/mP58ou2/BNbuUr3Hf2M0aOzthRVn8M5QurX71rR87sXr1h GGa/z6tT/Zds2y12+TpfP+nYOqp+/rYjZ4esXvzk0zkLlmtSv3rXjlx1/F3QMtzZgMfse1d9jvi1 t1zND2HScPUK2+2j+cl2uEmvl/Bh2Zat+4TH64gLruvzs599C3vSOqz+Yf1LvZ60estwn93ehdt9 ez5zk1vYJmrW5C9lWqNVJ5OnW4IjR31kudFWvqe5v/NWb/lE47n6jbOvo3xZhbOfMfLL7n97fRNb j9/WH9j+mgtTtsUW5hzNN6PVMx2/iMLO93ba798tfPp6d398tjyqfqFu+I9vv7XD1uY6Ofd/ci0/ o/5ZhR/2lvrVu3ZkK7PPX7ee2px1YzA9Mn77S/Nrlj/+1UdNlat37ciGCncCMyfuslsP/e7mazey y22j8Pi3fvWuHdlq9cYZap6H/wMqFm5yx9XfMwAAAABJRU5ErkJggg== "
height="107.96206"
width="163.36363" />
<rect
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3086"
width="417.54495"
height="126.4052"
x="141.08452"
y="114.51707"
rx="2.0839903"
ry="2.0839903" />
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="201.46712"
y="147.73848"
id="text3856"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3858"
x="201.46712"
y="147.73848"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">CASHIER</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3860"
y="182.10147"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="182.10147"
x="154.5717"
id="tspan3862"
sodipodi:role="line">Prefix: 40</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="200.85837"
id="text3149"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3151"
x="154.5717"
y="200.85837"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">ID: 4447190000</tspan></text>
</g>
<g
transform="translate(0,0.97855377)"
id="g3335">
<g
id="g3173"
transform="translate(0,-3.2620699)">
<text
sodipodi:linespacing="125%"
id="text3153"
y="341.12738"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="341.12738"
x="154.5717"
id="tspan3155"
sodipodi:role="line">Prefix: 42</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="359.88428"
id="text3157"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3159"
x="154.5717"
y="359.88428"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">ID: 1182180000</tspan></text>
</g>
<g
id="g3954"
transform="translate(0,-18.756902)">
<rect
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3876"
width="417.54495"
height="126.4052"
x="141.08452"
y="284.96024"
rx="2.0839903"
ry="2.0839903" />
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="209.6223"
y="318.18164"
id="text3878"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3880"
x="209.6223"
y="318.18164"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">CLIENT</tspan></text>
<image
width="162.31204"
height="107.26709"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAADyUlEQVR4 nO3a3Y6qShSFUTC+/yvXuSAxbCgQsPiZp8e46mgJq/ETxe6+lNId0vd913XDw8c/z+8d3zIYP2p8 y9LKLbcvbXN8y5Zt/jLn0jHZcnzm29z+m961cmn+vY/a5fXLg+F6kiWMZAkjWcJIljCSJYxkCSNZ wkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJI ljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYw kiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIl jGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxk CSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkj WcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nC 9KWUg4/s+67rhoePf/7LHJO55sfEWZYwj0t2eCG2XXmGe/f+l72rt7Z6U5s8r1832LbX+ZqlAc6b 85qpbln59SDs7afvN31MrZxlm5w/+r6fb6d644H9Huu1euOpcx6eqnrj0n7vXdnKsP31Iz+YnmWb TzZ+3Wx/wqoOrJzvfeml3HDO36ear1wa/saV62fovafYUspnv+tv8pWzbMPPA5NNjS8bL1Dd+9gt c36dqnrX+pNy78qJw8etlDJ53VY39U+ybZ+kjb9nGWm1cpfmc/5o6RwzfyHdu3LX8NvNw50seE3u a/J8XPC8bjH5bavXPdfP+XWqXG0TGm92fJTezXf2BJ8PRtsvzy/wzKkea3Je/yT6mqw41e0vjI27 vnjO/0evJx20+eeEd3f0vWnXx/OlC52TVA/f8P6yPsCPc64fk8NTRTt8GbfkffYZ5eJYu9ULiJU+ zp7z2FQpzqtocj4tpbyrdzSZY7zNJz8fKXP+NfNYhx/qf7BtuL+HR5Ay55OdcYpdOY+8Ss1n6Y9z pHTwqDmXvgGdl3HvypNMvtKa7/GU/+S695uB7Qf9yjkPpDD/hn/JvStbmcdaPSxnfTDoVn/PK783 +GXZBdcTS/utfoO7dPV218qGtl9RPO7/ZZuovkBv/5vcrqmqK5c2e+PKVu9Uwxa2PEf/AXnknj+O sxSLAAAAAElFTkSuQmCC "
id="image3951"
x="388.17426"
y="294.58957" />
</g>
</g>
<g
transform="translate(0,0.3261795)"
id="g3322">
<rect
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3964"
width="417.54495"
height="126.4052"
x="141.08452"
y="419.52063"
rx="2.0839903"
ry="2.0839903" />
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="209.6223"
y="452.74203"
id="text3966"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3968"
x="209.6223"
y="452.74203"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">WEIGHT</tspan></text>
<image
width="162.12962"
height="107.14654"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAAERElEQVR4 nO3a0ZKaQBRFUbX8/182D1QZInRzadDxTNZ6mjgNNrhBYHJ9PB6XIdfr9XK5TIvPf57/drJ8/ayR rVdaG9Wfc+Vd+vPc+3N/hv3XK68st2i5Xa09XNnS+sjKthfdjiwMnydZwkiWMJIljGQJI1nCSJYw kiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIl jGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxk CSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkj WcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nC SJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiW MJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCS Jcz18XgMLnm9Xi6XafH5z/8z+2Tp9H3iLEuYDyU7HV7njuT/dH/+9NLKid9o5/Zan+fYFnW+vFrT 27uv+hPb3AnLt1su0prSO/beWeVcr6XL1Ns0dLnNqy+OzeOskfV5Dm9RZ8BZe2N1YgfXWXlx11u/ Y2TftFTlM7rP/zFv/B378eDIp+I8V89enUO5MpMjXz7P9S/nP59V/3zWOiX317k6/9aw5TqPj9z0 eDyea+vfpd1Wt/ny7y3eN6jP88jX9wdu8Jfzn2wuWD84W1cOm8Navz1rZN/LfmidcW/H36nz9pUP oz7yUs6uuLa5dx+cB5/vvOmRWeuAb52ex0bunVL/W/Se8uDw+Dw3r1MHTnVjs5qvpP6m9QuG7/lu HNa5Trg3F/oVKrfSR05ge5dt3awMH5DPj7b+0KA/n+/xcrZ+7qhmsm/6JjpdfZ6dMZuLd+5yBuxa ydgHsbxsnS4N407Gy3BXkm3d6KyuqzLyTSrzXH5Cex+Cdt5ifoabBlT2SSWmutZGtVb4+UxP7+Sf v34979EGbl8+aWye9RuIuoMnv039Ge66AVruqy//lCcvzw3+XhjsvSH4Ke+YZ+dR/DfvijFBW9S6 071fylcCP644z19T2wc25GsvZzvnpnvrF1/rxHl2rvZWL3lbTxuK77V6ifmZaPpH+8vlZmeeYyPH ptqa8C3lnPTjj5OW6xz7dlr9Q93YrFoP7Vfz6s+kOM+DI/uWl63r095c0VnP8A8+M9/cF8XHN8Xn WfUT6nCvm2uo7Lf6lu6af32eu7aoo36X8jv/i/fqAXrwBrm1zr0rKa6heJzXt3TXE4P6PI/vk/lS lc/oD6RX6TSeNJuDAAAAAElFTkSuQmCC "
id="image4065"
x="387.35876"
y="429.14993" />
<g
transform="translate(0,140.26901)"
id="g3179">
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="341.12738"
id="text3181"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3183"
x="154.5717"
y="341.12738"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Prefix: 21</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3185"
y="359.88428"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="359.88428"
x="154.5717"
id="tspan3187"
sodipodi:role="line">ID: 12345</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="379.4567"
id="text3189"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3191"
x="154.5717"
y="379.4567"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Value: 67.89Kg</tspan></text>
</g>
</g>
<g
transform="translate(0,-1.9572678)"
id="g3308">
<rect
ry="2.0839903"
rx="2.0839903"
y="574.46893"
x="141.08452"
height="126.4052"
width="417.54495"
id="rect4081"
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<g
id="g3296">
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="195.7585"
y="607.69037"
id="text4083"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4085"
x="195.7585"
y="607.69037"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">DISCOUNT</tspan></text>
<image
y="584.09827"
x="385.72772"
id="image4202"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAADsElEQVR4 nO3aXXOiMACGUej4//8ye+EMZYHECBF96zlXHTd8iE8jYTtO0zQcMo7jMAz3zUs/b8ffLUcuXymN bHn92ZHtR3l2ZOnnpfazOvauS3toP3rLyPr5tGx1wM+ZjeF6kiWMZAkjWcJIljCSJYxkCSNZwkiW MJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCS JYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWM ZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJ I1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZ wkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJI ljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCjNM0 HdxyHIdhuG++/PmbuSZb3a+JWZYwH5fs/RfxL42kr9vuq6/4UmvZZ0qFZ3pdbVu5II0jSyezO777 0XdP4Fg549h0m7ozy75i/mjZZ0qFHXst7W0cx92RjZufPPrJkc+e1XKT3fe4sp5lr+81pb/zV2be wzyXzJ9TaXZZvl45gZbJqf3oZ0ZWBtdN0zTvrf6FvDPLvmKRa+E8W16K+nf36l+Xi+7XHf3kyIeD 6/tZpb/7Zv+bZd9yS9A4kQSN3FWaOe6zy3ZOumYhsT36s+fZ3eo3c3vE32TfteRi5cDlal8qvcKq qi4TX+U+4bb7ahd6fZfLrvwcVq+HBts9bMO9rUb0pdeOtiFWVj/v1fFz34Z7G46+yfrt+SdcuOu1 L1meUl+Qbc/h2Jr98IltHyMsD939mvy4Jfhk86p5tZquu+bKVxZqQ785a/Xc4PfGoPJA+OTfzfTd 5/dYfU5vPJN3Ka0p9//Dlvcq3Ql8j8pv7K3yNPvMM+Hu+0xXeq5ZuSwPr1Vp2931e+PRD5xnXw8f 2H3cX3L9ecuPpMu902on9Rn64dHbR5buWQ/Hvb1t3d2JG4PrlJ5itvzJ1e74px6Lth/9qfOsn2q7 9nt3s+ylSuvrMzts32f3kaWjH3hT901atv0Hm+wpnHOLKX0AAAAASUVORK5CYII= "
height="108.34499"
width="163.94308"
inkscape:transform-center-x="-24.4145"
inkscape:transform-center-y="6.3942733" />
<g
transform="translate(0,296.03285)"
id="g3210">
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="341.12738"
id="text3212"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3214"
x="154.5717"
y="341.12738"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Prefix: 44</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3216"
y="359.88428"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="359.88428"
x="154.5717"
id="tspan3218"
sodipodi:role="line">ID: 11111</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="379.4567"
id="text3220"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3222"
x="154.5717"
y="379.4567"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Value: 25%</tspan></text>
</g>
</g>
</g>
<g
transform="translate(0,-0.97866058)"
id="g3283">
<rect
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4115"
width="417.54495"
height="126.4052"
x="141.08452"
y="726.15521"
rx="2.0839903"
ry="2.0839903" />
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="212.88437"
y="759.37659"
id="text4117"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4119"
x="212.88437"
y="759.37659"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">PRICE</tspan></text>
<image
width="163.36363"
height="107.96206"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAAD70lEQVR4 nO3Z3XKbOhiGUezJ/d8yPfBsbwaB+Phz/aZrHaWukDB+goE8xnEcDnk8HsMwvDaf/tz+7/SVl3bR drbEkWvHZG3O/gytyvxrq6yt265emWfvyMq7K3qe2Rg+T7KEkSxhJEsYyRJGsoSRLGEkSxjJEkay hJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSR LGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxh JEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRL GMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJ EkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJG soSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLmMc4jge3 fDyGYXhtPv35X+aYtC4/Js6yhJHsX/M65bDXz/un2RG85ButPufvG9lX6fXYWp0v37VFK4M/c0wq 2z4XV118Ze/yi3PWX6zP+W0jN21uVT9Q9Zl37Wr9nV57TCrv8We6xrvx9/bnz7XTGTp70w5bWz1l ZGvvZzmbdnO5yvyVXa33cGE54zi+Z+vfpT2n2yz+fED7Tqb/nB7ZxZ3rfE99/8jzdn19HxhTVO/h qnLGcZydERYPxXOt6DavA3twctv6aeP7Rw7/fSSzD6YzrDLn21U3c/UebiqnDXc24Ge4gYeRd9i8 Tt31pf/ytZ9U5zrhlmTPq/+Opow8pp2/jaze69r83xnu7Gz93tWPPpdtD9Dil8hiBykj79O5Wths bnp3cezC429prxOOn2V3XXSv3ZC1AzZ988gLb2HbSRbPiPXL6MUXL3w0VFn6klVuP8u+7/vWfrPb 19NH3qR+A7R3zm82e24wjuON17KzlfqD68cuZeTHrP3hY/jKva1bu1O8K9nNK4Hi5r9mZN0vqO28 zvnu53VBs/aHjZMH7uQ17uLzuS8f+UmL63YuedeeNszmLPZwUzmbj+Gei0NPnjzqO9056KEjr9JO fv4ksvbEY/Pd9d/pVeW0l63LO7b4+Oa9zeG1+wMWT2Cbq6eMrOj31zmAxS+uk/t/x294X/3O5/+z +oV/F9mVbLvJxh6HjOyrnDKPfSK7fhk6c94xsq/4rO0Pc0/7XuEpWE8AAAAASUVORK5CYII= "
id="image4264"
x="386.54324"
y="734.96906" />
<g
transform="translate(0,442.82599)"
id="g3224">
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="341.12738"
id="text3226"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3228"
x="154.5717"
y="341.12738"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Prefix: 02</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3230"
y="359.88428"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="359.88428"
x="154.5717"
id="tspan3232"
sodipodi:role="line">ID: 99999</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="379.4567"
id="text3234"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3236"
x="154.5717"
y="379.4567"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Value: 134.50€</tspan></text>
</g>
</g>
<g
id="g3269">
<g
id="g3061"
transform="translate(0,284.6156)">
<g
id="g3063"
transform="translate(0,154.94832)">
<rect
ry="2.0839903"
rx="2.0839903"
y="438.27753"
x="141.08452"
height="126.4052"
width="417.54495"
id="rect3065"
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
sodipodi:linespacing="125%"
id="text3067"
y="471.49893"
x="216.61778"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="471.49893"
x="216.61778"
sodipodi:role="line"
id="tspan3083">UNIT</tspan></text>
<g
transform="translate(0,156.57936)"
id="g3071" />
</g>
</g>
<image
y="887.47076"
x="386.54324"
id="image3146"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAADz0lEQVR4
nO3Z0ZKaMACGUdnx/V+ZXjBjGWKyEQjyt+fcdIsBY/ZTgZ3meX7sMk3T4/FYdq/9XI5frB9db18/
Wh6nfJZyr/Yz9s+t/Yp65tw/22+N3Pe6asevhdQ/stPPkZ3hepIljGQJI1nCSJYwkiWMZAkjWcJI
ljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYw
kiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIl
jGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxk
CSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkj
WcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nC
SJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkzz
PO/cc5oej8ey+/rn/5k1KZ2+Jj5lCSNZwjyXf5ZP7NKJ32v9XwrtkZupNg743ZH3nNWgV3p8WZaD
9Oz4Uz7fCP1P0Rg5TVP5aG38d0fWfHFW/av36TofX5bXLm+PtvF8/TTuQuGUXl/W83y9zs3kX8d5
bb9yZM0dZtWzev0jy2f/9bA18zy/jtb+mr3oXLZ/9u3zgc2j7cOuH71+5K1m1b96B9d5+e+isUvt
OJv0336EDU/23I/Y0vruyfo45ZJdM7LmnrM6MnLQXbwy3M2AZ+2xU6Zy1iUXN7eO55RfYuM84Vnb
53hD1/R6wbXjP+z4d2Dt2ut4uJvP9ddhf9Zn0LvPQtrPesrIt19heu3Uv3r71nlEPOsjr2fyrF0t
/nrd1z7lH3cKe+dMj1+cjTbi91Jefi1XTsv209ekevl1w1OC8k084m39r+pfvY/WefT6b+4bzPNc
PZc95clqGzevs3/k2y30O/FUbbTa/YCByV7jzucJ9zf6FuRujVsQb/56sdnnrHfbwbOF2nwag7+1
ccfrGr2xf/XOWudye6dfb7b+vB13eq/HvZ1J+61f3ve+cuStZtW/emet845yytPW95NZ37PdOLfX
49dkH83zst/cR6v0xVn1r96gdW7r/2PE33tYI/76Vc7p+G2ED15b9ysaMfKes9q3emetc1vjjura
Hwkp3Xa7HcbMAAAAAElFTkSuQmCC
"
height="108.34499"
width="163.94308" />
<g
id="g3255"
transform="translate(0,598.58983)">
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="351.81107"
id="text3261"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3263"
x="154.5717"
y="351.81107"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">ID: 5449000000996</tspan></text>
</g>
</g>
<g
transform="matrix(0,-1,1,0,261.82237,1622.2884)"
id="g4150">
<text
xml:space="preserve"
style="font-size:8px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
x="618.97778"
y="320.0275"
id="text3357"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3359"
x="618.97778"
y="320.0275">This is a test sheet intended to help you test the codebar aquisition in OpenERP's Point of Sale module. </tspan><tspan
sodipodi:role="line"
x="618.97778"
y="330.0275"
id="tspan3363">The codes provided in this list are randomly chosen and are encoded in the EAN13 format. Their codes</tspan><tspan
sodipodi:role="line"
x="618.97778"
y="340.0275"
id="tspan3367">and prefixes are not intended to match any specified standard. </tspan></text>
<text
sodipodi:linespacing="125%"
id="text3369"
y="349.54001"
x="618.99207"
style="font-size:6.53564215px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
xml:space="preserve"><tspan
id="tspan3375"
y="349.54001"
x="618.99207"
sodipodi:role="line"
style="fill:#b3b3b3;fill-opacity:1">This document is licensed by OpenERP S.A. under the Creative Commons CC BY 3.0 license htttp://www.creativecommons.org</tspan></text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 70 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 75 KiB

View file

@ -0,0 +1,506 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="barcode_test_sheet.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.86706515"
inkscape:cx="381.55817"
inkscape:cy="597.57819"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1301"
inkscape:window-height="744"
inkscape:window-x="1985"
inkscape:window-y="24"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g4158"
transform="matrix(0.92675002,0,0,0.92675002,27.597551,38.360312)">
<text
sodipodi:linespacing="125%"
id="text2985"
y="72.12545"
x="140.86679"
style="font-size:46.51613998px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="72.12545"
x="140.86679"
id="tspan2987"
sodipodi:role="line">BARCODE TEST SHEET</tspan></text>
<g
transform="translate(0,-5.3405762e-5)"
id="g3347">
<image
y="124.14642"
x="388.17426"
id="image3083"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAADqUlEQVR4 nO3a226jMABFUYjy/7/MPCChDBfHARM4zVpP1dQY4u66JEw/DEO3S9/3XdeNh79+vRwz2hr5OmZr 5JH5t0YuX0X51W0dW3PNNa9xOWf5au8wsrxu9Ud95HHkYPg+yRJGsoSRLGEkSxjJEkayhJEsYSRL GMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJ EkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJG soSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKE kSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEs YSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEk SxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxh+mEY dh7Z913XjYe/fv3LrMlS8zWxyxJGsjuNGwbf91z911Z/1GY/18oJ689+cOTb7LZmPtJr/ZrcfOTu 1SucseaQlV221f6xnKdm5vqznzHy1Nn6vq9fk5SRrYzzry7RzHyXbd7r9HszXVP9b3bN/EdGlq/k 0y250uu0W2tSv3oXjvxo9d4ahmE6b/mP58ou2/BNbuUr3Hf2M0aOzthRVn8M5QurX71rR87sXr1h GGa/z6tT/Zds2y12+TpfP+nYOqp+/rYjZ4esXvzk0zkLlmtSv3rXjlx1/F3QMtzZgMfse1d9jvi1 t1zND2HScPUK2+2j+cl2uEmvl/Bh2Zat+4TH64gLruvzs599C3vSOqz+Yf1LvZ60estwn93ehdt9 ez5zk1vYJmrW5C9lWqNVJ5OnW4IjR31kudFWvqe5v/NWb/lE47n6jbOvo3xZhbOfMfLL7n97fRNb j9/WH9j+mgtTtsUW5hzNN6PVMx2/iMLO93ba798tfPp6d398tjyqfqFu+I9vv7XD1uY6Ofd/ci0/ o/5ZhR/2lvrVu3ZkK7PPX7ee2px1YzA9Mn77S/Nrlj/+1UdNlat37ciGCncCMyfuslsP/e7mazey y22j8Pi3fvWuHdlq9cYZap6H/wMqFm5yx9XfMwAAAABJRU5ErkJggg== "
height="107.96206"
width="163.36363" />
<rect
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3086"
width="417.54495"
height="126.4052"
x="141.08452"
y="114.51707"
rx="2.0839903"
ry="2.0839903" />
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="201.46712"
y="147.73848"
id="text3856"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3858"
x="201.46712"
y="147.73848"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">CASHIER</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3860"
y="182.10147"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="182.10147"
x="154.5717"
id="tspan3862"
sodipodi:role="line">Prefix: 40</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="200.85837"
id="text3149"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3151"
x="154.5717"
y="200.85837"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">ID: 4447190000</tspan></text>
</g>
<g
transform="translate(0,0.97855377)"
id="g3335">
<g
id="g3173"
transform="translate(0,-3.2620699)">
<text
sodipodi:linespacing="125%"
id="text3153"
y="341.12738"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="341.12738"
x="154.5717"
id="tspan3155"
sodipodi:role="line">Prefix: 42</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="359.88428"
id="text3157"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3159"
x="154.5717"
y="359.88428"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">ID: 1182180000</tspan></text>
</g>
<g
id="g3954"
transform="translate(0,-18.756902)">
<rect
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3876"
width="417.54495"
height="126.4052"
x="141.08452"
y="284.96024"
rx="2.0839903"
ry="2.0839903" />
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="209.6223"
y="318.18164"
id="text3878"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3880"
x="209.6223"
y="318.18164"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">CLIENT</tspan></text>
<image
width="162.31204"
height="107.26709"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAADyUlEQVR4 nO3a3Y6qShSFUTC+/yvXuSAxbCgQsPiZp8e46mgJq/ETxe6+lNId0vd913XDw8c/z+8d3zIYP2p8 y9LKLbcvbXN8y5Zt/jLn0jHZcnzm29z+m961cmn+vY/a5fXLg+F6kiWMZAkjWcJIljCSJYxkCSNZ wkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJI ljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYw kiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIl jGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxk CSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkj WcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nC 9KWUg4/s+67rhoePf/7LHJO55sfEWZYwj0t2eCG2XXmGe/f+l72rt7Z6U5s8r1832LbX+ZqlAc6b 85qpbln59SDs7afvN31MrZxlm5w/+r6fb6d644H9Huu1euOpcx6eqnrj0n7vXdnKsP31Iz+YnmWb TzZ+3Wx/wqoOrJzvfeml3HDO36ear1wa/saV62fovafYUspnv+tv8pWzbMPPA5NNjS8bL1Dd+9gt c36dqnrX+pNy78qJw8etlDJ53VY39U+ybZ+kjb9nGWm1cpfmc/5o6RwzfyHdu3LX8NvNw50seE3u a/J8XPC8bjH5bavXPdfP+XWqXG0TGm92fJTezXf2BJ8PRtsvzy/wzKkea3Je/yT6mqw41e0vjI27 vnjO/0evJx20+eeEd3f0vWnXx/OlC52TVA/f8P6yPsCPc64fk8NTRTt8GbfkffYZ5eJYu9ULiJU+ zp7z2FQpzqtocj4tpbyrdzSZY7zNJz8fKXP+NfNYhx/qf7BtuL+HR5Ay55OdcYpdOY+8Ss1n6Y9z pHTwqDmXvgGdl3HvypNMvtKa7/GU/+S695uB7Qf9yjkPpDD/hn/JvStbmcdaPSxnfTDoVn/PK783 +GXZBdcTS/utfoO7dPV218qGtl9RPO7/ZZuovkBv/5vcrqmqK5c2e+PKVu9Uwxa2PEf/AXnknj+O sxSLAAAAAElFTkSuQmCC "
id="image3951"
x="388.17426"
y="294.58957" />
</g>
</g>
<g
transform="translate(0,0.3261795)"
id="g3322">
<rect
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3964"
width="417.54495"
height="126.4052"
x="141.08452"
y="419.52063"
rx="2.0839903"
ry="2.0839903" />
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="209.6223"
y="452.74203"
id="text3966"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3968"
x="209.6223"
y="452.74203"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">WEIGHT</tspan></text>
<image
width="162.12962"
height="107.14654"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAAERElEQVR4 nO3a0ZKaQBRFUbX8/182D1QZInRzadDxTNZ6mjgNNrhBYHJ9PB6XIdfr9XK5TIvPf57/drJ8/ayR rVdaG9Wfc+Vd+vPc+3N/hv3XK68st2i5Xa09XNnS+sjKthfdjiwMnydZwkiWMJIljGQJI1nCSJYw kiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIl jGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxk CSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkj WcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nC SJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiW MJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCS Jcz18XgMLnm9Xi6XafH5z/8z+2Tp9H3iLEuYDyU7HV7njuT/dH/+9NLKid9o5/Zan+fYFnW+vFrT 27uv+hPb3AnLt1su0prSO/beWeVcr6XL1Ns0dLnNqy+OzeOskfV5Dm9RZ8BZe2N1YgfXWXlx11u/ Y2TftFTlM7rP/zFv/B378eDIp+I8V89enUO5MpMjXz7P9S/nP59V/3zWOiX317k6/9aw5TqPj9z0 eDyea+vfpd1Wt/ny7y3eN6jP88jX9wdu8Jfzn2wuWD84W1cOm8Navz1rZN/LfmidcW/H36nz9pUP oz7yUs6uuLa5dx+cB5/vvOmRWeuAb52ex0bunVL/W/Se8uDw+Dw3r1MHTnVjs5qvpP6m9QuG7/lu HNa5Trg3F/oVKrfSR05ge5dt3awMH5DPj7b+0KA/n+/xcrZ+7qhmsm/6JjpdfZ6dMZuLd+5yBuxa ydgHsbxsnS4N407Gy3BXkm3d6KyuqzLyTSrzXH5Cex+Cdt5ifoabBlT2SSWmutZGtVb4+UxP7+Sf v34979EGbl8+aWye9RuIuoMnv039Ge66AVruqy//lCcvzw3+XhjsvSH4Ke+YZ+dR/DfvijFBW9S6 071fylcCP644z19T2wc25GsvZzvnpnvrF1/rxHl2rvZWL3lbTxuK77V6ifmZaPpH+8vlZmeeYyPH ptqa8C3lnPTjj5OW6xz7dlr9Q93YrFoP7Vfz6s+kOM+DI/uWl63r095c0VnP8A8+M9/cF8XHN8Xn WfUT6nCvm2uo7Lf6lu6af32eu7aoo36X8jv/i/fqAXrwBrm1zr0rKa6heJzXt3TXE4P6PI/vk/lS lc/oD6RX6TSeNJuDAAAAAElFTkSuQmCC "
id="image4065"
x="387.35876"
y="429.14993" />
<g
transform="translate(0,140.26901)"
id="g3179">
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="341.12738"
id="text3181"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3183"
x="154.5717"
y="341.12738"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Prefix: 21</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3185"
y="359.88428"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="359.88428"
x="154.5717"
id="tspan3187"
sodipodi:role="line">ID: 12345</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="379.4567"
id="text3189"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3191"
x="154.5717"
y="379.4567"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Value: 67.89Kg</tspan></text>
</g>
</g>
<g
transform="translate(0,-1.9572678)"
id="g3308">
<rect
ry="2.0839903"
rx="2.0839903"
y="574.46893"
x="141.08452"
height="126.4052"
width="417.54495"
id="rect4081"
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<g
id="g3296">
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="195.7585"
y="607.69037"
id="text4083"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4085"
x="195.7585"
y="607.69037"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">DISCOUNT</tspan></text>
<image
y="584.09827"
x="385.72772"
id="image4202"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAADsElEQVR4 nO3aXXOiMACGUej4//8ye+EMZYHECBF96zlXHTd8iE8jYTtO0zQcMo7jMAz3zUs/b8ffLUcuXymN bHn92ZHtR3l2ZOnnpfazOvauS3toP3rLyPr5tGx1wM+ZjeF6kiWMZAkjWcJIljCSJYxkCSNZwkiW MJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCS JYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWM ZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJ I1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZ wkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJI ljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCjNM0 HdxyHIdhuG++/PmbuSZb3a+JWZYwH5fs/RfxL42kr9vuq6/4UmvZZ0qFZ3pdbVu5II0jSyezO777 0XdP4Fg549h0m7ozy75i/mjZZ0qFHXst7W0cx92RjZufPPrJkc+e1XKT3fe4sp5lr+81pb/zV2be wzyXzJ9TaXZZvl45gZbJqf3oZ0ZWBtdN0zTvrf6FvDPLvmKRa+E8W16K+nf36l+Xi+7XHf3kyIeD 6/tZpb/7Zv+bZd9yS9A4kQSN3FWaOe6zy3ZOumYhsT36s+fZ3eo3c3vE32TfteRi5cDlal8qvcKq qi4TX+U+4bb7ahd6fZfLrvwcVq+HBts9bMO9rUb0pdeOtiFWVj/v1fFz34Z7G46+yfrt+SdcuOu1 L1meUl+Qbc/h2Jr98IltHyMsD939mvy4Jfhk86p5tZquu+bKVxZqQ785a/Xc4PfGoPJA+OTfzfTd 5/dYfU5vPJN3Ka0p9//Dlvcq3Ql8j8pv7K3yNPvMM+Hu+0xXeq5ZuSwPr1Vp2931e+PRD5xnXw8f 2H3cX3L9ecuPpMu902on9Rn64dHbR5buWQ/Hvb1t3d2JG4PrlJ5itvzJ1e74px6Lth/9qfOsn2q7 9nt3s+ylSuvrMzts32f3kaWjH3hT901atv0Hm+wpnHOLKX0AAAAASUVORK5CYII= "
height="108.34499"
width="163.94308"
inkscape:transform-center-x="-24.4145"
inkscape:transform-center-y="6.3942733" />
<g
transform="translate(0,296.03285)"
id="g3210">
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="341.12738"
id="text3212"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3214"
x="154.5717"
y="341.12738"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Prefix: 44</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3216"
y="359.88428"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="359.88428"
x="154.5717"
id="tspan3218"
sodipodi:role="line">ID: 11111</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="379.4567"
id="text3220"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3222"
x="154.5717"
y="379.4567"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Value: 25%</tspan></text>
</g>
</g>
</g>
<g
transform="translate(0,-0.97866058)"
id="g3283">
<rect
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4115"
width="417.54495"
height="126.4052"
x="141.08452"
y="726.15521"
rx="2.0839903"
ry="2.0839903" />
<text
xml:space="preserve"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="212.88437"
y="759.37659"
id="text4117"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4119"
x="212.88437"
y="759.37659"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">PRICE</tspan></text>
<image
width="163.36363"
height="107.96206"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAAD70lEQVR4 nO3Z3XKbOhiGUezJ/d8yPfBsbwaB+Phz/aZrHaWukDB+goE8xnEcDnk8HsMwvDaf/tz+7/SVl3bR drbEkWvHZG3O/gytyvxrq6yt265emWfvyMq7K3qe2Rg+T7KEkSxhJEsYyRJGsoSRLGEkSxjJEkay hJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSR LGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxh JEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRL GMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJ EkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJG soSRLGEkSxjJEkayhJEsYSRLGMkSRrKEkSxhJEsYyRJGsoSRLGEkSxjJEkayhJEsYSRLmMc4jge3 fDyGYXhtPv35X+aYtC4/Js6yhJHsX/M65bDXz/un2RG85ButPufvG9lX6fXYWp0v37VFK4M/c0wq 2z4XV118Ze/yi3PWX6zP+W0jN21uVT9Q9Zl37Wr9nV57TCrv8We6xrvx9/bnz7XTGTp70w5bWz1l ZGvvZzmbdnO5yvyVXa33cGE54zi+Z+vfpT2n2yz+fED7Tqb/nB7ZxZ3rfE99/8jzdn19HxhTVO/h qnLGcZydERYPxXOt6DavA3twctv6aeP7Rw7/fSSzD6YzrDLn21U3c/UebiqnDXc24Ge4gYeRd9i8 Tt31pf/ytZ9U5zrhlmTPq/+Opow8pp2/jaze69r83xnu7Gz93tWPPpdtD9Dil8hiBykj79O5Wths bnp3cezC429prxOOn2V3XXSv3ZC1AzZ988gLb2HbSRbPiPXL6MUXL3w0VFn6klVuP8u+7/vWfrPb 19NH3qR+A7R3zm82e24wjuON17KzlfqD68cuZeTHrP3hY/jKva1bu1O8K9nNK4Hi5r9mZN0vqO28 zvnu53VBs/aHjZMH7uQ17uLzuS8f+UmL63YuedeeNszmLPZwUzmbj+Gei0NPnjzqO9056KEjr9JO fv4ksvbEY/Pd9d/pVeW0l63LO7b4+Oa9zeG1+wMWT2Cbq6eMrOj31zmAxS+uk/t/x294X/3O5/+z +oV/F9mVbLvJxh6HjOyrnDKPfSK7fhk6c94xsq/4rO0Pc0/7XuEpWE8AAAAASUVORK5CYII= "
id="image4264"
x="386.54324"
y="734.96906" />
<g
transform="translate(0,442.82599)"
id="g3224">
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="341.12738"
id="text3226"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3228"
x="154.5717"
y="341.12738"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Prefix: 02</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3230"
y="359.88428"
x="154.5717"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="359.88428"
x="154.5717"
id="tspan3232"
sodipodi:role="line">ID: 99999</tspan></text>
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="379.4567"
id="text3234"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3236"
x="154.5717"
y="379.4567"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">Value: 134.50€</tspan></text>
</g>
</g>
<g
id="g3269">
<g
id="g3061"
transform="translate(0,284.6156)">
<g
id="g3063"
transform="translate(0,154.94832)">
<rect
ry="2.0839903"
rx="2.0839903"
y="438.27753"
x="141.08452"
height="126.4052"
width="417.54495"
id="rect3065"
style="fill:none;stroke:#c3c3c3;stroke-width:1.07903957;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
sodipodi:linespacing="125%"
id="text3067"
y="471.49893"
x="216.61778"
style="font-size:27.53050041px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
y="471.49893"
x="216.61778"
sodipodi:role="line"
id="tspan3083">UNIT</tspan></text>
<g
transform="translate(0,156.57936)"
id="g3071" />
</g>
</g>
<image
y="887.47076"
x="386.54324"
id="image3146"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAACYCAIAAAB/IAJdAAAAA3NCSVQICAjb4U/gAAADz0lEQVR4 nO3Z0ZKaMACGUdnx/V+ZXjBjGWKyEQjyt+fcdIsBY/ZTgZ3meX7sMk3T4/FYdq/9XI5frB9db18/ Wh6nfJZyr/Yz9s+t/Yp65tw/22+N3Pe6asevhdQ/stPPkZ3hepIljGQJI1nCSJYwkiWMZAkjWcJI ljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYw kiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIl jGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxk CSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkj WcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nC SJYwkiWMZAkjWcJIljCSJYxkCSNZwkiWMJIljGQJI1nCSJYwkiWMZAkjWcJIljCSJYxkCSNZwkzz PO/cc5oej8ey+/rn/5k1KZ2+Jj5lCSNZwjyXf5ZP7NKJ32v9XwrtkZupNg743ZH3nNWgV3p8WZaD 9Oz4Uz7fCP1P0Rg5TVP5aG38d0fWfHFW/av36TofX5bXLm+PtvF8/TTuQuGUXl/W83y9zs3kX8d5 bb9yZM0dZtWzev0jy2f/9bA18zy/jtb+mr3oXLZ/9u3zgc2j7cOuH71+5K1m1b96B9d5+e+isUvt OJv0336EDU/23I/Y0vruyfo45ZJdM7LmnrM6MnLQXbwy3M2AZ+2xU6Zy1iUXN7eO55RfYuM84Vnb 53hD1/R6wbXjP+z4d2Dt2ut4uJvP9ddhf9Zn0LvPQtrPesrIt19heu3Uv3r71nlEPOsjr2fyrF0t /nrd1z7lH3cKe+dMj1+cjTbi91Jefi1XTsv209ekevl1w1OC8k084m39r+pfvY/WefT6b+4bzPNc PZc95clqGzevs3/k2y30O/FUbbTa/YCByV7jzucJ9zf6FuRujVsQb/56sdnnrHfbwbOF2nwag7+1 ccfrGr2xf/XOWudye6dfb7b+vB13eq/HvZ1J+61f3ve+cuStZtW/emet845yytPW95NZ37PdOLfX 49dkH83zst/cR6v0xVn1r96gdW7r/2PE33tYI/76Vc7p+G2ED15b9ysaMfKes9q3emetc1vjjura Hwkp3Xa7HcbMAAAAAElFTkSuQmCC "
height="108.34499"
width="163.94308" />
<g
id="g3255"
transform="translate(0,598.58983)">
<text
xml:space="preserve"
style="font-size:17.41555405px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="154.5717"
y="351.81107"
id="text3261"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3263"
x="154.5717"
y="351.81107"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium">ID: 5449000000996</tspan></text>
</g>
</g>
<g
transform="matrix(0,-1,1,0,261.82237,1622.2884)"
id="g4150">
<text
xml:space="preserve"
style="font-size:8px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
x="618.97778"
y="320.0275"
id="text3357"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3359"
x="618.97778"
y="320.0275">This is a test sheet intended to help you test the codebar aquisition in OpenERP's Point of Sale module. </tspan><tspan
sodipodi:role="line"
x="618.97778"
y="330.0275"
id="tspan3363">The codes provided in this list are randomly chosen and are encoded in the EAN13 format. Their codes</tspan><tspan
sodipodi:role="line"
x="618.97778"
y="340.0275"
id="tspan3367">and prefixes are not intended to match any specified standard. </tspan></text>
<text
sodipodi:linespacing="125%"
id="text3369"
y="349.54001"
x="618.99207"
style="font-size:6.53564215px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
xml:space="preserve"><tspan
id="tspan3375"
y="349.54001"
x="618.99207"
sodipodi:role="line"
style="fill:#b3b3b3;fill-opacity:1">This document is licensed by OpenERP S.A. under the Creative Commons CC BY 3.0 license htttp://www.creativecommons.org</tspan></text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,218 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * point_of_sale
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Odoo 9.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-08-18 14:06+0000\n"
"PO-Revision-Date: 2016-05-31 19:03+0000\n"
"Last-Translator: Martin Trigaux\n"
"Language-Team: Spanish (Bolivia) (http://www.transifex.com/odoo/odoo-9/"
"language/es_BO/)\n"
"Language: es_BO\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: point_of_sale
#: model:ir.model.fields,field_description:point_of_sale.field_report_pos_order__average_price
msgid "Average Price"
msgstr "Precio promedio"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:0
#, python-format
msgid "Change"
msgstr "Cambiar"
#. module: point_of_sale
#: model:ir.model.fields,field_description:point_of_sale.field_closing_balance_confirm_wizard__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_category__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_config__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_details_wizard__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_make_payment__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order_line__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_pack_operation_lot__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_payment__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_payment_method__create_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_session__create_date
msgid "Created on"
msgstr "Creado en"
#. module: point_of_sale
#: model:ir.model.fields,field_description:point_of_sale.field_pos_config__currency_id
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order__currency_id
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order_line__currency_id
#: model:ir.model.fields,field_description:point_of_sale.field_pos_payment__currency_id
#: model:ir.model.fields,field_description:point_of_sale.field_pos_session__currency_id
msgid "Currency"
msgstr "Divisa"
#. module: point_of_sale
#: model:ir.model.fields.selection,name:point_of_sale.selection__pos_session__state__opened
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_session_search
msgid "In Progress"
msgstr "En proceso"
#. module: point_of_sale
#: model:ir.model.fields,field_description:point_of_sale.field_closing_balance_confirm_wizard__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_category__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_config__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_details_wizard__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_make_payment__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order_line__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_pack_operation_lot__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_payment__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_payment_method__write_uid
#: model:ir.model.fields,field_description:point_of_sale.field_pos_session__write_uid
msgid "Last Updated by"
msgstr "Última actualización de"
#. module: point_of_sale
#: model:ir.model.fields,field_description:point_of_sale.field_closing_balance_confirm_wizard__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_category__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_config__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_details_wizard__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_make_payment__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order_line__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_pack_operation_lot__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_payment__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_payment_method__write_date
#: model:ir.model.fields,field_description:point_of_sale.field_pos_session__write_date
msgid "Last Updated on"
msgstr "Última actualización en"
#. module: point_of_sale
#: model:ir.model.fields,field_description:point_of_sale.field_report_pos_order__date
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_order_filter
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_report_pos_order_search
msgid "Order Date"
msgstr "Fecha orden"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.action_pos_config_kanban
#: model:ir.actions.act_window,name:point_of_sale.action_pos_config_pos
#: model:ir.model.fields,field_description:point_of_sale.field_pos_config__name
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order__config_id
#: model:ir.model.fields,field_description:point_of_sale.field_pos_session__config_id
#: model:ir.model.fields,field_description:point_of_sale.field_report_pos_order__config_id
#: model:ir.ui.menu,name:point_of_sale.menu_point_root
#: model:ir.ui.menu,name:point_of_sale.menu_pos_config_pos
#: model_terms:ir.ui.view,arch_db:point_of_sale.digest_digest_view_form
#: model_terms:ir.ui.view,arch_db:point_of_sale.product_template_form_view
#: model_terms:ir.ui.view,arch_db:point_of_sale.res_config_settings_view_form
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_account_journal_pos_user_form
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_session_search
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_report_pos_order_search
msgid "Point of Sale"
msgstr "Punto de Venta"
#. module: point_of_sale
#: model:ir.model,name:point_of_sale.model_pos_category
#: model:ir.model.fields,field_description:point_of_sale.field_product_product__pos_categ_id
#: model:ir.model.fields,field_description:point_of_sale.field_product_template__pos_categ_id
msgid "Point of Sale Category"
msgstr "Categoría del PdV"
#. module: point_of_sale
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_config_search
msgid "Point of Sale Config"
msgstr "Configuración del PdV"
#. module: point_of_sale
#: model:ir.model,name:point_of_sale.model_pos_config
#: model:ir.model.fields,field_description:point_of_sale.field_pos_make_payment__config_id
#: model_terms:ir.ui.view,arch_db:point_of_sale.pos_config_view_form
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_config_tree
msgid "Point of Sale Configuration"
msgstr "Configuración del PdV"
#. module: point_of_sale
#: model:ir.model,name:point_of_sale.model_pos_order
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_order_search
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_pos_form
msgid "Point of Sale Orders"
msgstr "Órdenes PdV"
#. module: point_of_sale
#: model:ir.model,name:point_of_sale.model_pos_session
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_session_form
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_session_search
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_session_tree
msgid "Point of Sale Session"
msgstr "Sesión PdV"
#. module: point_of_sale
#: model:ir.model.fields.selection,name:point_of_sale.selection__pos_order__state__done
#: model:ir.model.fields.selection,name:point_of_sale.selection__report_pos_order__state__done
#: model_terms:ir.ui.view,arch_db:point_of_sale.view_pos_order_filter
msgid "Posted"
msgstr "Asentado"
#. module: point_of_sale
#: model:ir.model.fields,field_description:point_of_sale.field_report_pos_order__product_qty
msgid "Product Quantity"
msgstr "Cantidad del producto"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:0
#, python-format
msgid "Tax ID"
msgstr "NIT"
#. module: point_of_sale
#: model:ir.model.fields,help:point_of_sale.field_pos_order__config_id
#: model:ir.model.fields,help:point_of_sale.field_pos_session__config_id
msgid "The physical point of sale you will use."
msgstr "El PdV físico que utilizará."
#. module: point_of_sale
#: model:ir.model.fields,field_description:point_of_sale.field_pos_order_line__price_unit
msgid "Unit Price"
msgstr "Precio unidad"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:0
#, python-format
msgid "VAT:"
msgstr "CIF/NIT:"
#. module: point_of_sale
#: code:addons/point_of_sale/wizard/pos_open_statement.py:0
#, python-format
msgid ""
"You have to define which payment method must be available in the point of "
"sale by reusing existing bank and cash through \"Accounting / "
"Configuration / Journals / Journals\". Select a journal and check the field "
"\"PoS Payment Method\" from the \"Point of Sale\" tab. You can also create "
"new payment methods directly from menu \"PoS Backend / Configuration / "
"Payment Methods\"."
msgstr ""
"Puede definir qué método de pago estará disponible en el PdV reusando los "
"bancos y cajas existentes a través de \"Contabilidad / Configuración / "
"Diarios / Diarios\". Seleccione un diario y marque la casilla \"Método de "
"pago de PdV\" desde la pestaña PdV. Puede crear también métodos de pago "
"directamente desde el menú \"Backend PdV / Configuración / Métodos de pago\"."
#. module: point_of_sale
#: code:addons/point_of_sale/models/pos_session.py:0
#, python-format
msgid "You should assign a Point of Sale to your session."
msgstr "Debe asignar un PdV a su sesión."
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:0
#, python-format
msgid "ZIP"
msgstr "Casilla"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import account_bank_statement
from . import account_cash_rounding
from . import account_payment
from . import account_journal
from . import account_tax
from . import account_move
from . import barcode_rule
from . import chart_template
from . import digest
from . import pos_category
from . import pos_config
from . import pos_order
from . import pos_session
from . import product
from . import res_partner
from . import res_company
from . import res_config_settings
from . import stock_picking
from . import stock_rule
from . import stock_warehouse
from . import pos_payment
from . import pos_payment_method
from . import pos_bill

View file

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
# Copyright (C) 2004-2008 PC Solutions (<http://pcsol.be>). All Rights Reserved
from odoo import fields, models, api, _
from odoo.exceptions import UserError
class AccountBankStatementLine(models.Model):
_inherit = 'account.bank.statement.line'
pos_session_id = fields.Many2one('pos.session', string="Session", copy=False)

View file

@ -0,0 +1,11 @@
from odoo import api, models, _
from odoo.exceptions import UserError
class AccountCashRounding(models.Model):
_inherit = 'account.cash.rounding'
@api.ondelete(at_uninstall=False)
def _unlink_except_pos_config(self):
if self.env['pos.config'].search_count([('rounding_method', 'in', self.ids)], limit=1):
raise UserError(_('You cannot delete a rounding method that is used in a Point of Sale configuration.'))

View file

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
# Copyright (C) 2004-2008 PC Solutions (<http://pcsol.be>). All Rights Reserved
from odoo import fields, models, api, _
from odoo.exceptions import ValidationError
class AccountJournal(models.Model):
_inherit = 'account.journal'
pos_payment_method_ids = fields.One2many('pos.payment.method', 'journal_id', string='Point of Sale Payment Methods')
@api.constrains('type')
def _check_type(self):
methods = self.env['pos.payment.method'].sudo().search([("journal_id", "in", self.ids)])
if methods:
raise ValidationError(_("This journal is associated with a payment method. You cannot modify its type"))
def _check_no_active_payments(self):
hanging_journal_entries = self.env['pos.payment'].search(
[
('payment_method_id', 'in', self.pos_payment_method_ids.ids),
('session_id.state', '=', 'opened')
], limit=1)
if(hanging_journal_entries):
payment_method = hanging_journal_entries.payment_method_id.name
pos_order = hanging_journal_entries.pos_order_id.name
pos_session = hanging_journal_entries.session_id.name
raise ValidationError(_("This journal is associated with payment method %s that is being used by order %s in the active pos session %s", payment_method, pos_order, pos_session))
@api.ondelete(at_uninstall=False)
def _unlink_journal_except_with_active_payments(self):
for journal in self:
journal._check_no_active_payments()
def action_archive(self):
self._check_no_active_payments()
return super().action_archive()
def _get_journal_inbound_outstanding_payment_accounts(self):
res = super()._get_journal_inbound_outstanding_payment_accounts()
account_ids = set(res.ids)
for payment_method in self.sudo().pos_payment_method_ids:
account_ids.add(payment_method.outstanding_account_id.id or self.company_id.account_journal_payment_debit_account_id.id)
return self.env['account.account'].browse(account_ids)

View file

@ -0,0 +1,85 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, api
class AccountMove(models.Model):
_inherit = 'account.move'
pos_order_ids = fields.One2many('pos.order', 'account_move')
pos_payment_ids = fields.One2many('pos.payment', 'account_move_id')
@api.depends('tax_cash_basis_created_move_ids')
def _compute_always_tax_exigible(self):
super()._compute_always_tax_exigible()
# The pos closing move does not create caba entries (anymore); we set the tax values directly on the closing move.
# (But there may still be old closing moves that used caba entries from previous versions.)
relevant_moves = self.filtered(lambda move: not (move.always_tax_exigible or move.tax_cash_basis_created_move_ids))
if not relevant_moves:
return
sessions = self.env['pos.session'].with_context(active_test=False).search([
('move_id', 'in', relevant_moves.ids),
])
sessions.move_id.always_tax_exigible = True
def _stock_account_get_last_step_stock_moves(self):
stock_moves = super(AccountMove, self)._stock_account_get_last_step_stock_moves()
for invoice in self.filtered(lambda x: x.move_type == 'out_invoice'):
stock_moves += invoice.sudo().mapped('pos_order_ids.picking_ids.move_ids').filtered(lambda x: x.state == 'done' and x.location_dest_id.usage == 'customer')
for invoice in self.filtered(lambda x: x.move_type == 'out_refund'):
stock_moves += invoice.sudo().mapped('pos_order_ids.picking_ids.move_ids').filtered(lambda x: x.state == 'done' and x.location_id.usage == 'customer')
return stock_moves
def _get_invoiced_lot_values(self):
self.ensure_one()
lot_values = super(AccountMove, self)._get_invoiced_lot_values()
if self.state == 'draft':
return lot_values
# user may not have access to POS orders, but it's ok if they have
# access to the invoice
for order in self.sudo().pos_order_ids:
for line in order.lines:
lots = line.pack_lot_ids or False
if lots:
for lot in lots:
lot_values.append({
'product_name': lot.product_id.name,
'quantity': line.qty if lot.product_id.tracking == 'lot' else 1.0,
'uom_name': line.product_uom_id.name,
'lot_name': lot.lot_name,
'pos_lot_id': lot.id,
})
return lot_values
def _compute_payments_widget_reconciled_info(self):
"""Add pos_payment_name field in the reconciled vals to be able to show the payment method in the invoice."""
super()._compute_payments_widget_reconciled_info()
for move in self:
if move.invoice_payments_widget:
if move.state == 'posted' and move.is_invoice(include_receipts=True):
reconciled_partials = move._get_all_reconciled_invoice_partials()
for i, reconciled_partial in enumerate(reconciled_partials):
counterpart_line = reconciled_partial['aml']
pos_payment = counterpart_line.move_id.sudo().pos_payment_ids
move.invoice_payments_widget['content'][i].update({
'pos_payment_name': pos_payment.payment_method_id.name,
})
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
def _stock_account_get_anglo_saxon_price_unit(self):
self.ensure_one()
if not self.product_id:
return self.price_unit
price_unit = super(AccountMoveLine, self)._stock_account_get_anglo_saxon_price_unit()
sudo_order = self.move_id.sudo().pos_order_ids
if sudo_order:
price_unit = sudo_order._get_pos_anglo_saxon_price_unit(self.product_id, self.move_id.partner_id.id, self.quantity)
return price_unit

View file

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, fields, api
class AccountPayment(models.Model):
_inherit = 'account.payment'
pos_payment_method_id = fields.Many2one('pos.payment.method', "POS Payment Method")
force_outstanding_account_id = fields.Many2one("account.account", "Forced Outstanding Account", check_company=True)
pos_session_id = fields.Many2one('pos.session', "POS Session")
def _get_valid_liquidity_accounts(self):
result = super()._get_valid_liquidity_accounts()
return result | self.pos_payment_method_id.outstanding_account_id
@api.depends("force_outstanding_account_id")
def _compute_outstanding_account_id(self):
"""When force_outstanding_account_id is set, we use it as the outstanding_account_id."""
super()._compute_outstanding_account_id()
for payment in self:
if payment.force_outstanding_account_id:
payment.outstanding_account_id = payment.force_outstanding_account_id

View file

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from odoo import _, api, models
from odoo.exceptions import UserError
from odoo.tools import split_every
class AccountTax(models.Model):
_inherit = 'account.tax'
def write(self, vals):
forbidden_fields = {
'amount_type', 'amount', 'type_tax_use', 'tax_group_id', 'price_include',
'include_base_amount', 'is_base_affected',
}
if forbidden_fields & set(vals.keys()):
lines = self.env['pos.order.line'].sudo().search([
('order_id.session_id.state', '!=', 'closed')
])
self_ids = set(self.ids)
for lines_chunk in map(self.env['pos.order.line'].sudo().browse, split_every(100000, lines.ids)):
if any(tid in self_ids for ts in lines_chunk.read(['tax_ids']) for tid in ts['tax_ids']):
raise UserError(_(
'It is forbidden to modify a tax used in a POS order not posted. '
'You must close the POS sessions before modifying the tax.'
))
lines_chunk.invalidate_cache(['tax_ids'], lines_chunk.ids)
return super(AccountTax, self).write(vals)

View file

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, fields
from odoo.tools.translate import _
class BarcodeRule(models.Model):
_inherit = 'barcode.rule'
type = fields.Selection(selection_add=[
('weight', 'Weighted Product'),
('price', 'Priced Product'),
('discount', 'Discounted Product'),
('client', 'Client'),
('cashier', 'Cashier')
], ondelete={
'weight': 'set default',
'price': 'set default',
'discount': 'set default',
'client': 'set default',
'cashier': 'set default',
})

View file

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from odoo import api, models
class AccountChartTemplate(models.Model):
_inherit = 'account.chart.template'
def _load(self, company):
"""Remove the payment methods that are created for the company before installing the chart of accounts.
Keeping these existing pos.payment.method records interferes with the installation of chart of accounts
because pos.payment.method model has fields linked to account.journal and account.account records that are
deleted during the loading of chart of accounts.
"""
self.env['pos.payment.method'].search([('company_id', '=', company.id)]).unlink()
result = super(AccountChartTemplate, self)._load(company)
self.env['pos.config'].post_install_pos_localisation(companies=company)
return result

View file

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, _
from odoo.exceptions import AccessError
class Digest(models.Model):
_inherit = 'digest.digest'
kpi_pos_total = fields.Boolean('POS Sales')
kpi_pos_total_value = fields.Monetary(compute='_compute_kpi_pos_total_value')
def _compute_kpi_pos_total_value(self):
if not self.env.user.has_group('point_of_sale.group_pos_user'):
raise AccessError(_("Do not have access, skip this data for user's digest email"))
for record in self:
start, end, company = record._get_kpi_compute_parameters()
record.kpi_pos_total_value = sum(self.env['pos.order'].search([
('date_order', '>=', start),
('date_order', '<', end),
('state', 'not in', ['draft', 'cancel', 'invoiced']),
('company_id', '=', company.id)
]).mapped('amount_total'))
def _compute_kpis_actions(self, company, user):
res = super(Digest, self)._compute_kpis_actions(company, user)
res['kpi_pos_total'] = 'point_of_sale.action_pos_sale_graph&menu_id=%s' % self.env.ref('point_of_sale.menu_point_root').id
return res

View file

@ -0,0 +1,21 @@
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class Bill(models.Model):
_name = "pos.bill"
_order = "value"
_description = "Coins/Bills"
name = fields.Char("Name")
value = fields.Float("Coin/Bill Value", required=True, digits=(16, 4))
pos_config_ids = fields.Many2many("pos.config", string="Point of Sales")
@api.model
def name_create(self, name):
try:
value = float(name)
except:
raise UserError(_("The name of the Coins/Bills must be a number."))
result = super().create({"name": name, "value": value})
return result.name_get()[0]

Some files were not shown because too many files have changed in this diff Show more