Manage expiration of sale quotation

Closes #11166
This commit is contained in:
Cédric Krier
2025-02-07 16:24:12 +01:00
parent ebd5a5f414
commit ae2609bec6
14 changed files with 384 additions and 150 deletions
+1
View File
@@ -1,3 +1,4 @@
* Manage expiration of quotation
* Add relate to open products from sale
Version 7.4.0 - 2024-11-04
+6 -4
View File
@@ -4,12 +4,17 @@
from trytond.pool import Pool
from . import (
configuration, invoice, party, product, sale, sale_reporting, stock)
configuration, invoice, ir, party, product, sale, sale_reporting, stock)
def register():
Pool.register(
ir.Cron,
stock.Move,
configuration.Configuration,
configuration.ConfigurationSequence,
configuration.ConfigurationSaleMethod,
configuration.ConfigurationQuotation,
sale.Sale,
sale.SaleIgnoredInvoice,
sale.SaleRecreatedInvoice,
@@ -31,9 +36,6 @@ def register():
sale.HandleShipmentExceptionAsk,
sale.HandleInvoiceExceptionAsk,
sale.ReturnSaleStart,
configuration.Configuration,
configuration.ConfigurationSequence,
configuration.ConfigurationSaleMethod,
sale_reporting.Context,
sale_reporting.Main,
sale_reporting.MainTimeseries,
+17
View File
@@ -1,5 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import datetime as dt
from trytond.model import (
ModelSingleton, ModelSQL, ModelView, ValueMixin, fields)
from trytond.modules.company.model import (
@@ -11,6 +14,12 @@ sale_invoice_method = fields.Selection(
'get_sale_invoice_methods', "Sale Invoice Method")
sale_shipment_method = fields.Selection(
'get_sale_shipment_methods', "Sale Shipment Method")
sale_quotation_validity = fields.TimeDelta(
"Sale Quotation Validity",
domain=['OR',
('sale_quotation_validity', '>=', dt.timedelta()),
('sale_quotation_validity', '=', None),
])
def get_sale_methods(field_name):
@@ -41,6 +50,7 @@ class Configuration(
[Eval('context', {}).get('company', -1), None]),
('sequence_type', '=', Id('sale', 'sequence_type_sale')),
]))
sale_quotation_validity = fields.MultiValue(sale_quotation_validity)
sale_invoice_method = fields.MultiValue(sale_invoice_method)
get_sale_invoice_methods = get_sale_methods('invoice_method')
sale_shipment_method = fields.MultiValue(sale_shipment_method)
@@ -62,6 +72,8 @@ class Configuration(
return pool.get('sale.configuration.sale_method')
if field == 'sale_sequence':
return pool.get('sale.configuration.sequence')
elif field == 'sale_quotation_validity':
return pool.get('sale.configuration.quotation')
return super(Configuration, cls).multivalue_model(field)
default_sale_sequence = default_func('sale_sequence')
@@ -102,3 +114,8 @@ class ConfigurationSaleMethod(ModelSQL, ValueMixin):
@classmethod
def default_sale_shipment_method(cls):
return 'order'
class ConfigurationQuotation(ModelSQL, ValueMixin):
__name__ = 'sale.configuration.quotation'
sale_quotation_validity = sale_quotation_validity
+24
View File
@@ -28,6 +28,30 @@ In order to change these without needing to remove the sales lines you can use
the :guilabel:`Modify Header` button to start the
`Modify Header <wizard-sale.modify_header>` wizard.
.. _Sending a quotation:
Sending a quotation
===================
A draft `Sale <model-sale.sale>` can be set to a quotation state with a
validity period to calculate an expiration date based from the quotation date.
The quotation can then be sent to the customer for confirmation.
The validity of a quotation can be extended by resetting to draft and edit the
:guilabel:`Quotation Validity`.
In order to change the quotation date, you can use the :guilabel:`Modify
Header` button to start the `Modify Header <wizard-sale.modify_header>` wizard
which will update the prices.
.. note::
A quotation with a sale date after the expiration date cannot be confirmed.
.. note::
If an quotation reaches its expiration without being confirmed, it will be
automatically cancelled by a `scheduled task <trytond:model-ir.cron>`.
.. _Shipping a sale:
Shipping a sale
+16
View File
@@ -0,0 +1,16 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import PoolMeta
class Cron(metaclass=PoolMeta):
__name__ = 'ir.cron'
@classmethod
def __setup__(cls):
super().__setup__()
cls.method.selection.extend([
('sale.sale|cancel_expired_quotation',
"Cancel Expired Sale Quotation"),
])
+134 -129
View File
@@ -1,24 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
<office:meta><meta:generator>LibreOffice/7.6.4.1$Linux_X86_64 LibreOffice_project/60$Build-1</meta:generator><meta:creation-date>2008-06-07T15:28:22</meta:creation-date><dc:date>2009-01-10T16:03:33</dc:date><meta:editing-cycles>1</meta:editing-cycles><meta:editing-duration>PT0S</meta:editing-duration><meta:document-statistic meta:table-count="3" meta:image-count="0" meta:object-count="0" meta:page-count="7" meta:paragraph-count="96" meta:word-count="216" meta:character-count="2488" meta:non-whitespace-character-count="2367"/><meta:user-defined meta:name="Info 1"/><meta:user-defined meta:name="Info 2"/><meta:user-defined meta:name="Info 3"/><meta:user-defined meta:name="Info 4"/></office:meta>
<office:meta><meta:generator>LibreOffice/24.2.7.2$Linux_X86_64 LibreOffice_project/420$Build-2</meta:generator><meta:creation-date>2008-06-07T15:28:22</meta:creation-date><dc:date>2009-01-10T16:03:33</dc:date><meta:editing-cycles>1</meta:editing-cycles><meta:editing-duration>PT0S</meta:editing-duration><meta:document-statistic meta:table-count="3" meta:image-count="0" meta:object-count="0" meta:page-count="7" meta:paragraph-count="99" meta:word-count="236" meta:character-count="2719" meta:non-whitespace-character-count="2581"/><meta:user-defined meta:name="Info 1"/><meta:user-defined meta:name="Info 2"/><meta:user-defined meta:name="Info 3"/><meta:user-defined meta:name="Info 4"/></office:meta>
<office:settings>
<config:config-item-set config:name="ooo:view-settings">
<config:config-item config:name="ViewAreaTop" config:type="long">0</config:config-item>
<config:config-item config:name="ViewAreaTop" config:type="long">39582</config:config-item>
<config:config-item config:name="ViewAreaLeft" config:type="long">0</config:config-item>
<config:config-item config:name="ViewAreaWidth" config:type="long">48129</config:config-item>
<config:config-item config:name="ViewAreaHeight" config:type="long">23973</config:config-item>
<config:config-item config:name="ViewAreaWidth" config:type="long">48103</config:config-item>
<config:config-item config:name="ViewAreaHeight" config:type="long">22915</config:config-item>
<config:config-item config:name="ShowRedlineChanges" config:type="boolean">true</config:config-item>
<config:config-item config:name="InBrowseMode" config:type="boolean">false</config:config-item>
<config:config-item-map-indexed config:name="Views">
<config:config-item-map-entry>
<config:config-item config:name="ViewId" config:type="string">view2</config:config-item>
<config:config-item config:name="ViewLeft" config:type="long">7856</config:config-item>
<config:config-item config:name="ViewTop" config:type="long">9275</config:config-item>
<config:config-item config:name="ViewLeft" config:type="long">5339</config:config-item>
<config:config-item config:name="ViewTop" config:type="long">46011</config:config-item>
<config:config-item config:name="VisibleLeft" config:type="long">0</config:config-item>
<config:config-item config:name="VisibleTop" config:type="long">0</config:config-item>
<config:config-item config:name="VisibleRight" config:type="long">48128</config:config-item>
<config:config-item config:name="VisibleBottom" config:type="long">23971</config:config-item>
<config:config-item config:name="VisibleTop" config:type="long">39582</config:config-item>
<config:config-item config:name="VisibleRight" config:type="long">48101</config:config-item>
<config:config-item config:name="VisibleBottom" config:type="long">62495</config:config-item>
<config:config-item config:name="ZoomType" config:type="short">0</config:config-item>
<config:config-item config:name="ViewLayoutColumns" config:type="short">0</config:config-item>
<config:config-item config:name="ViewLayoutBookMode" config:type="boolean">false</config:config-item>
@@ -33,113 +33,116 @@
</config:config-item-map-indexed>
</config:config-item-set>
<config:config-item-set config:name="ooo:configuration-settings">
<config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintProspectRTL" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item>
<config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item>
<config:config-item config:name="AutoFirstLineIndentDisregardLineSpace" config:type="boolean">false</config:config-item>
<config:config-item config:name="HeaderSpacingBelowLastPara" config:type="boolean">false</config:config-item>
<config:config-item config:name="ProtectBookmarks" config:type="boolean">false</config:config-item>
<config:config-item config:name="ContinuousEndnotes" config:type="boolean">false</config:config-item>
<config:config-item config:name="DisableOffPagePositioning" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item>
<config:config-item config:name="SubtractFlysAnchoredAtFlys" config:type="boolean">true</config:config-item>
<config:config-item config:name="ApplyParagraphMarkFormatToNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintFaxName" config:type="string"/>
<config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item>
<config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item>
<config:config-item config:name="NoNumberingShowFollowBy" config:type="boolean">false</config:config-item>
<config:config-item config:name="HyphenateURLs" config:type="boolean">true</config:config-item>
<config:config-item config:name="ImagePreferredDPI" config:type="int">0</config:config-item>
<config:config-item config:name="FootnoteInColumnToPageEnd" config:type="boolean">true</config:config-item>
<config:config-item config:name="GutterAtTop" config:type="boolean">false</config:config-item>
<config:config-item config:name="ContinuousEndnotes" config:type="boolean">false</config:config-item>
<config:config-item config:name="FrameAutowidthWithMorePara" config:type="boolean">false</config:config-item>
<config:config-item config:name="SubtractFlysAnchoredAtFlys" config:type="boolean">true</config:config-item>
<config:config-item config:name="SurroundTextWrapSmall" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item>
<config:config-item config:name="TreatSingleColumnBreakAsPageBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="PropLineSpacingShrinksFirstLine" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabOverSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="AutoFirstLineIndentDisregardLineSpace" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabOverMargin" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedComplexScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmbedLatinScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmbedOnlyUsedFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="ClippedPictures" config:type="boolean">false</config:config-item>
<config:config-item config:name="FrameAutowidthWithMorePara" config:type="boolean">false</config:config-item>
<config:config-item config:name="FloattableNomargins" config:type="boolean">false</config:config-item>
<config:config-item config:name="UnbreakableNumberings" config:type="boolean">false</config:config-item>
<config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="RsidRoot" config:type="int">204959</config:config-item>
<config:config-item config:name="PrinterPaperFromSetup" config:type="boolean">false</config:config-item>
<config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/>
<config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
<config:config-item config:name="Rsid" config:type="int">1972400</config:config-item>
<config:config-item config:name="FootnoteInColumnToPageEnd" config:type="boolean">true</config:config-item>
<config:config-item config:name="ProtectFields" config:type="boolean">false</config:config-item>
<config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item>
<config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item>
<config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item>
<config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmbedSystemFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddParaLineSpacingToTableCells" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
<config:config-item config:name="HyphenateURLs" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">true</config:config-item>
<config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item>
<config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
<config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="ImagePreferredDPI" config:type="int">0</config:config-item>
<config:config-item config:name="PrinterSetup" config:type="base64Binary"/>
<config:config-item config:name="SmallCapsPercentage66" config:type="boolean">true</config:config-item>
<config:config-item config:name="AlignTabStopPosition" config:type="boolean">true</config:config-item>
<config:config-item config:name="DropCapPunctuation" config:type="boolean">false</config:config-item>
<config:config-item config:name="MathBaselineAlignment" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterName" config:type="string"/>
<config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
<config:config-item config:name="AddParaTableSpacing" config:type="boolean">true</config:config-item>
<config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item>
<config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
<config:config-item config:name="TabOverflow" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item>
<config:config-item config:name="ApplyUserData" config:type="boolean">false</config:config-item>
<config:config-item config:name="MsWordCompMinLineHeightByFly" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item>
<config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/>
<config:config-item config:name="EmbedAsianScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item>
<config:config-item config:name="ApplyTextAttrToEmptyLineAtEndOfParagraph" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedSystemFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="DisableOffPagePositioning" config:type="boolean">true</config:config-item>
<config:config-item config:name="BackgroundParaOverDrawings" config:type="boolean">false</config:config-item>
<config:config-item config:name="SaveThumbnail" config:type="boolean">true</config:config-item>
<config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbeddedDatabaseName" config:type="string"/>
<config:config-item config:name="ProtectForm" config:type="boolean">false</config:config-item>
<config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item>
<config:config-item config:name="MsWordCompTrailingBlanks" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmptyDbFieldHidesPara" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabOverflow" config:type="boolean">false</config:config-item>
<config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="ProtectBookmarks" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="TableRowKeep" config:type="boolean">false</config:config-item>
<config:config-item config:name="NoNumberingShowFollowBy" config:type="boolean">false</config:config-item>
<config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
<config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item>
<config:config-item config:name="GutterAtTop" config:type="boolean">false</config:config-item>
<config:config-item config:name="StylesNoDefault" config:type="boolean">false</config:config-item>
<config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">false</config:config-item>
<config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
<config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item>
<config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="CurrentDatabaseCommand" config:type="string"/>
<config:config-item config:name="ApplyParagraphMarkFormatToNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
<config:config-item config:name="JustifyLinesWithShrinking" config:type="boolean">false</config:config-item>
<config:config-item config:name="RsidRoot" config:type="int">204959</config:config-item>
<config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item>
<config:config-item config:name="CollapseEmptyCellPara" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item>
<config:config-item config:name="CurrentDatabaseCommand" config:type="string"/>
<config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/>
<config:config-item config:name="SaveThumbnail" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmbeddedDatabaseName" config:type="string"/>
<config:config-item config:name="UnbreakableNumberings" config:type="boolean">false</config:config-item>
<config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item>
<config:config-item config:name="MsWordCompTrailingBlanks" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddParaTableSpacing" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrinterPaperFromSetup" config:type="boolean">false</config:config-item>
<config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
<config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">true</config:config-item>
<config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="PropLineSpacingShrinksFirstLine" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item>
<config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
<config:config-item config:name="HeaderSpacingBelowLastPara" config:type="boolean">false</config:config-item>
<config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
<config:config-item config:name="ClippedPictures" config:type="boolean">false</config:config-item>
<config:config-item config:name="MathBaselineAlignment" config:type="boolean">false</config:config-item>
<config:config-item config:name="AlignTabStopPosition" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterName" config:type="string"/>
<config:config-item config:name="AddParaLineSpacingToTableCells" config:type="boolean">false</config:config-item>
<config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
<config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
<config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedLatinScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrinterSetup" config:type="base64Binary"/>
<config:config-item config:name="UseVariableWidthNBSP" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedOnlyUsedFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="ApplyUserData" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">true</config:config-item>
<config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="ProtectFields" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item>
<config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item>
<config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">false</config:config-item>
<config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
<config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">false</config:config-item>
<config:config-item config:name="StylesNoDefault" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="NoGapAfterNoteNumber" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmptyDbFieldHidesPara" config:type="boolean">false</config:config-item>
<config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
<config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item>
<config:config-item config:name="DropCapPunctuation" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">false</config:config-item>
<config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/>
<config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item>
<config:config-item config:name="Rsid" config:type="int">2203069</config:config-item>
<config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
<config:config-item config:name="ProtectForm" config:type="boolean">false</config:config-item>
<config:config-item config:name="MsWordCompMinLineHeightByFly" config:type="boolean">false</config:config-item>
<config:config-item config:name="SmallCapsPercentage66" config:type="boolean">true</config:config-item>
</config:config-item-set>
</office:settings>
<office:scripts>
@@ -597,22 +600,22 @@
<style:text-properties officeooo:paragraph-rsid="001ac103"/>
</style:style>
<style:style style:name="P34" style:family="paragraph" style:parent-style-name="Text_20_body">
<loext:graphic-properties draw:fill-gradient-name="gradient" draw:fill-hatch-name="hatch"/>
<style:text-properties officeooo:paragraph-rsid="001ac103"/>
</style:style>
<style:style style:name="P35" style:family="paragraph" style:parent-style-name="Text_20_body">
<loext:graphic-properties draw:fill-gradient-name="gradient" draw:fill-hatch-name="hatch"/>
<style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false" fo:keep-with-next="auto"/>
<style:text-properties officeooo:rsid="001ac103" officeooo:paragraph-rsid="001ac103"/>
</style:style>
<style:style style:name="P35" style:family="paragraph" style:parent-style-name="Text_20_body" style:master-page-name="">
<style:style style:name="P36" style:family="paragraph" style:parent-style-name="Text_20_body" style:master-page-name="">
<loext:graphic-properties draw:fill-gradient-name="gradient" draw:fill-hatch-name="hatch"/>
<style:paragraph-properties style:page-number="auto" fo:break-before="column" fo:keep-with-next="auto"/>
<style:text-properties officeooo:rsid="001ac103" officeooo:paragraph-rsid="001ac103"/>
</style:style>
<style:style style:name="P36" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:font-size="12pt" officeooo:paragraph-rsid="00066dfa" style:font-size-asian="12pt" style:font-size-complex="12pt"/>
</style:style>
<style:style style:name="P37" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:font-size="12pt" officeooo:paragraph-rsid="001be9bb" style:font-size-asian="12pt" style:font-size-complex="12pt"/>
<style:style style:name="P37" style:family="paragraph" style:parent-style-name="Text_20_body">
<loext:graphic-properties draw:fill-gradient-name="gradient" draw:fill-hatch-name="hatch"/>
<style:text-properties officeooo:rsid="002014be" officeooo:paragraph-rsid="002014be"/>
</style:style>
<style:style style:name="T1" style:family="text">
<style:text-properties officeooo:rsid="001ac103"/>
@@ -709,11 +712,14 @@
<text:section text:style-name="Sect1" text:name="Section1">
<text:p text:style-name="P26">Description: <text:placeholder text:placeholder-type="text">&lt;sale.description or &apos;&apos;&gt;</text:placeholder></text:p>
<text:p text:style-name="P24">Reference: <text:placeholder text:placeholder-type="text">&lt;sale.reference or &apos;&apos;&gt;</text:placeholder></text:p>
<text:p text:style-name="P32">Date: <text:placeholder text:placeholder-type="text">&lt;format_date(sale.sale_date or today, sale.party.lang)&gt;</text:placeholder></text:p>
<text:p text:style-name="P35">Delivery Address:</text:p>
<text:p text:style-name="P34"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;line in sale.delivery_full_address.splitlines()&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P34"><text:placeholder text:placeholder-type="text">&lt;line&gt;</text:placeholder></text:p>
<text:p text:style-name="P34"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
<text:p text:style-name="P32">Date: <text:placeholder text:placeholder-type="text">&lt;format_date((sale.quotation_date if sale.state in [&apos;draft&apos;, &apos;quotation&apos;] and sale.quotation_date else sale.sale_date) or today, sale.party.lang)&gt;</text:placeholder></text:p>
<text:p text:style-name="P34"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;sale.state in [&apos;draft&apos;, &apos;quotation&apos;] and sale.quotation_expire&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P37">Expiration Date: <text:placeholder text:placeholder-type="text">&lt;format_date(sale.quotation_expire, sale.party.lang)&gt;</text:placeholder></text:p>
<text:p text:style-name="P34"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
<text:p text:style-name="P36">Delivery Address:</text:p>
<text:p text:style-name="P35"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;line in sale.delivery_full_address.splitlines()&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P35"><text:placeholder text:placeholder-type="text">&lt;line&gt;</text:placeholder></text:p>
<text:p text:style-name="P35"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
</text:section>
<table:table table:name="Table1" table:style-name="Table1">
<table:table-column table:style-name="Table1.A"/>
@@ -769,25 +775,25 @@
<text:p text:style-name="P27"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;line.product_name&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P27"><text:placeholder text:placeholder-type="text">&lt;line.product_name&gt;</text:placeholder></text:p>
<text:p text:style-name="P27"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
<text:p text:style-name="P27"><text:soft-page-break/><text:placeholder text:placeholder-type="text">&lt;if test=&quot;line.description&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P27"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;line.description&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P27"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;description in line.description.split(&apos;\n&apos;)&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P29"><text:placeholder text:placeholder-type="text">&lt;description&gt;</text:placeholder></text:p>
<text:p text:style-name="P29"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
<text:p text:style-name="P29"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.B5" office:value-type="string">
<text:p text:style-name="P19"><text:placeholder text:placeholder-type="text">&lt;format_number_symbol(line.quantity, sale.party.lang, line.unit, digits=line.unit.digits) if line.unit else format_number(line.quantity, sale.party.lang)&gt;</text:placeholder><text:soft-page-break/></text:p>
<text:p text:style-name="P19"><text:placeholder text:placeholder-type="text">&lt;format_number_symbol(line.quantity, sale.party.lang, line.unit, digits=line.unit.digits) if line.unit else format_number(line.quantity, sale.party.lang)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.B5" office:value-type="string">
<text:p text:style-name="P20"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.unit_price, sale.party.lang, sale.currency, digits=line.__class__.unit_price.digits[1])&gt;</text:placeholder><text:soft-page-break/></text:p>
<text:p text:style-name="P20"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.unit_price, sale.party.lang, sale.currency, digits=line.__class__.unit_price.digits[1])&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.B5" office:value-type="string">
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;tax in line.taxes&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:soft-page-break/><text:placeholder text:placeholder-type="text">&lt;tax.description&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;tax.description&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.E5" office:value-type="string">
<text:p text:style-name="P19"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.amount, sale.party.lang, sale.currency)&gt;</text:placeholder><text:soft-page-break/></text:p>
<text:p text:style-name="P19"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.amount, sale.party.lang, sale.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
</table:table-row>
<table:table-row>
@@ -811,14 +817,14 @@
<table:table-row>
<table:table-cell table:style-name="Table1.A8" table:number-columns-spanned="4" office:value-type="string">
<text:p text:style-name="Heading_20_2"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;description in (line.description or &apos;&apos;).split(&apos;\n&apos;)&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="Heading_20_2"><text:placeholder text:placeholder-type="text">&lt;description&gt;</text:placeholder></text:p>
<text:p text:style-name="Heading_20_2"><text:soft-page-break/><text:placeholder text:placeholder-type="text">&lt;description&gt;</text:placeholder></text:p>
<text:p text:style-name="P13"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:table-cell table:style-name="Table1.E5" office:value-type="string">
<text:p text:style-name="P19"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.amount, sale.party.lang, sale.currency)&gt;</text:placeholder></text:p>
<text:p text:style-name="P19"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.amount, sale.party.lang, sale.currency)&gt;</text:placeholder><text:soft-page-break/></text:p>
</table:table-cell>
</table:table-row>
<table:table-row>
@@ -839,7 +845,6 @@
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
<text:soft-page-break/>
<table:table-row>
<table:table-cell table:style-name="Table1.A11" table:number-columns-spanned="5" office:value-type="string">
<text:p text:style-name="Heading_20_2"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;description in (line.description or &apos;&apos;).split(&apos;\n&apos;)&quot;&gt;</text:placeholder></text:p>
@@ -898,6 +903,7 @@
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
<text:soft-page-break/>
<table:table-row>
<table:table-cell table:style-name="Table1.A2" table:number-columns-spanned="5" office:value-type="string">
<text:p text:style-name="Table_20_Contents"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
@@ -912,7 +918,6 @@
<table:table table:name="Table2" table:style-name="Table2">
<table:table-column table:style-name="Table2.A"/>
<table:table-column table:style-name="Table2.B"/>
<text:soft-page-break/>
<table:table-row>
<table:table-cell office:value-type="string">
<text:p text:style-name="Table_20_Contents"/>
@@ -950,10 +955,10 @@
</table:table-cell>
</table:table-row>
</table:table>
<text:p text:style-name="Text_20_body"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;comment in (sale.comment or &apos;&apos;).split(&apos;\n&apos;)&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="Text_20_body"><text:soft-page-break/><text:placeholder text:placeholder-type="text">&lt;for each=&quot;comment in (sale.comment or &apos;&apos;).split(&apos;\n&apos;)&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="Text_20_body"><text:placeholder text:placeholder-type="text">&lt;comment&gt;</text:placeholder></text:p>
<text:p text:style-name="Text_20_body"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
<text:p text:style-name="Text_20_body"><text:soft-page-break/><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
<text:p text:style-name="Text_20_body"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
</office:text>
</office:body>
</office:document>
+95 -3
View File
@@ -7,7 +7,8 @@ from decimal import Decimal
from functools import partial
from itertools import chain, groupby
from sql import Null
from sql import Literal, Null, operators
from sql.conditionals import Coalesce
from sql.functions import CharLength
from trytond import backend
@@ -89,7 +90,39 @@ class Sale(
states={
'readonly': Eval('state') != 'draft',
})
quotation_date = fields.Date(
"Quotation Date",
states={
'readonly': (
(Eval('state') != 'draft')
| (Eval('number') & Eval('lines'))),
'invisible': ~Eval('state').in_(['draft', 'quotation']),
},
help="When the quotation was edited.")
quotation_validity = fields.TimeDelta(
"Quotation Validity",
domain=['OR',
('quotation_validity', '>=', datetime.timedelta()),
('quotation_validity', '=', None),
],
states={
'readonly': Eval('state') != 'draft',
'invisible': ~Eval('state').in_(['draft', 'quotation']),
},
help="How much time the quotation is valid.")
quotation_expire = fields.Function(fields.Date(
"Quotation Expire",
states={
'invisible': ~Eval('state').in_(['draft', 'quotation']),
},
help="Until when the quotation is still valid."),
'on_change_with_quotation_expire')
sale_date = fields.Date('Sale Date',
domain=[
If(Eval('quotation_expire') & (Eval('state') == 'confirmed'),
('sale_date', '<=', Eval('quotation_expire')),
()),
],
states={
'readonly': ~Eval('state').in_(['draft', 'quotation']),
'required': ~Eval('state').in_(
@@ -437,6 +470,8 @@ class Sale(
@fields.depends('company')
def on_change_company(self):
self.quotation_validity = self.default_quotation_validity(
company=self.company.id if self.company else None)
self.payment_term = self.default_payment_term(
company=self.company.id if self.company else None)
self.invoice_method = self.default_invoice_method(
@@ -444,6 +479,43 @@ class Sale(
self.shipment_method = self.default_shipment_method(
company=self.company.id if self.company else None)
@classmethod
def default_quotation_validity(cls, **pattern):
Config = Pool().get('sale.configuration')
config = Config(1)
return config.get_multivalue('sale_quotation_validity', **pattern)
@fields.depends('company', 'quotation_date', 'quotation_validity')
def on_change_with_quotation_expire(self, name=None):
pool = Pool()
Date = pool.get('ir.date')
if self.quotation_validity is not None:
with Transaction().set_context(
company=self.company.id if self.company else None):
today = Date.today()
return (self.quotation_date or today) + self.quotation_validity
@classmethod
def domain_quotation_expire(cls, domain, tables):
pool = Pool()
Date = pool.get('ir.date')
today = Date.today()
field = cls.quotation_expire._field
table, _ = tables[None]
name, operator, value = domain
Operator = fields.SQL_OPERATORS[operator]
column = (
Coalesce(table.quotation_date, today) + Coalesce(
table.quotation_validity, datetime.timedelta()))
expression = Operator(column, field._domain_value(operator, value))
if isinstance(expression, operators.In) and not expression.right:
expression = Literal(False)
elif isinstance(expression, operators.NotIn) and not expression.right:
expression = Literal(True)
expression = field._domain_add_null(
column, operator, value, expression)
return expression
@staticmethod
def default_state():
return 'draft'
@@ -1061,8 +1133,16 @@ class Sale(
@Workflow.transition('quotation')
@set_employee('quoted_by')
def quote(cls, sales):
for sale in sales:
sale.check_for_quotation()
pool = Pool()
Date = pool.get('ir.date')
for company, c_sales in groupby(sales, key=lambda s: s.company):
with Transaction().set_context(company=company.id):
today = Date.today()
for sale in c_sales:
sale.check_for_quotation()
if not sale.quotation_date:
sale.quotation_date = today
cls.save(sales)
cls.set_number(sales)
@property
@@ -1223,6 +1303,18 @@ class Sale(
def modify_header(cls, sales):
pass
@classmethod
def cancel_expired_quotation(cls):
pool = Pool()
Date = pool.get('ir.date')
today = Date.today()
sales = cls.search([
('state', '=', 'quotation'),
('quotation_expire', '<', today),
('company', '=', Transaction().context.get('company', -1)),
])
cls.cancel(sales)
class SaleIgnoredInvoice(ModelSQL):
__name__ = 'sale.sale-ignored-account.invoice'
+8
View File
@@ -554,4 +554,12 @@ this repository contains the full copyright notices and license terms. -->
<field name="action" ref="wizard_sale_open_product"/>
</record>
</data>
<data noupdate="1">
<record model="ir.cron" id="cron_cancel_expired_quotation">
<field name="method">sale.sale|cancel_expired_quotation</field>
<field name="interval_number" eval="1"/>
<field name="interval_type">days</field>
</record>
</data>
</tryton>
@@ -0,0 +1,57 @@
=======================
Sale Quotation Scenario
=======================
Imports::
>>> import datetime as dt
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import create_chart
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual
>>> today = dt.date.today()
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
>>> Cron = Model.get('ir.cron')
>>> Sale = Model.get('sale.sale')
>>> SaleConfiguration = Model.get('sale.configuration')
>>> Party = Model.get('party.party')
Set quotation validity to 1 week::
>>> sale_configuration = SaleConfiguration(1)
>>> sale_configuration.sale_quotation_validity = dt.timedelta(weeks=1)
>>> sale_configuration.save()
Create customer::
>>> customer = Party(name="Customer")
>>> customer.save()
Create a quotation::
>>> sale = Sale(party=customer)
>>> sale.click('quote')
>>> sale.state
'quotation'
>>> assertEqual(sale.quotation_date, today)
>>> assertEqual(sale.quotation_validity, dt.timedelta(weeks=1))
>>> assertEqual(sale.quotation_expire, today + dt.timedelta(weeks=1))
Expire quotation::
>>> sale.quotation_date = today - dt.timedelta(weeks=2)
>>> sale.save()
>>> cron, = Cron.find(
... [('method', '=', 'sale.sale|cancel_expired_quotation')], limit=1)
>>> cron.click('run_once')
>>> sale.reload()
>>> sale.state
'cancelled'
+2
View File
@@ -10,6 +10,8 @@ this repository contains the full copyright notices and license terms. -->
<label name="sale_shipment_method" />
<field name="sale_shipment_method" />
<newline/>
<label name="sale_quotation_validity"/>
<field name="sale_quotation_validity"/>
<label name="sale_process_after"/>
<field name="sale_process_after"/>
</form>
+20 -10
View File
@@ -25,18 +25,29 @@ this repository contains the full copyright notices and license terms. -->
<field name="reference"/>
<notebook colspan="6">
<page string="Sale" id="sale">
<page string="Sale" id="sale" col="6">
<label name="sale_date"/>
<field name="sale_date"/>
<label name="payment_term"/>
<field name="payment_term"/>
<label name="warehouse"/>
<field name="warehouse"/>
<label name="currency"/>
<field name="currency"/>
<field name="lines" colspan="4"
view_ids="sale.sale_line_view_tree_sequence"/>
<group col="2" colspan="2" id="states" yfill="1">
<label name="quotation_date"/>
<field name="quotation_date"/>
<label name="quotation_validity"/>
<field name="quotation_validity"/>
<label name="quotation_expire"/>
<field name="quotation_expire"/>
<label name="warehouse"/>
<field name="warehouse"/>
<label name="shipping_date"/>
<field name="shipping_date"/>
<field name="lines" colspan="6" view_ids="sale.sale_line_view_tree_sequence"/>
<group col="2" colspan="3" id="states" yfill="1">
<label name="invoice_state"/>
<field name="invoice_state"/>
<label name="shipment_state"/>
@@ -44,7 +55,7 @@ this repository contains the full copyright notices and license terms. -->
<label name="state"/>
<field name="state"/>
</group>
<group col="10" colspan="2" id="amount" yfill="1">
<group col="10" colspan="3" id="amount" yfill="1">
<label name="untaxed_amount" xalign="1.0" xexpand="1" xfill="0"/>
<field name="untaxed_amount" xalign="1.0" xexpand="0"/>
<newline/>
@@ -62,13 +73,12 @@ this repository contains the full copyright notices and license terms. -->
<field name="company"/>
<label name="origin"/>
<field name="origin"/>
<label name="invoice_method"/>
<field name="invoice_method"/>
<label name="shipment_method"/>
<field name="shipment_method"/>
<label name="shipping_date"/>
<field name="shipping_date"/>
<newline/>
<label name="quoted_by"/>
<field name="quoted_by"/>
<label name="confirmed_by"/>
+1
View File
@@ -5,6 +5,7 @@ this repository contains the full copyright notices and license terms. -->
<field name="company" expand="1" optional="1"/>
<field name="number" expand="1"/>
<field name="reference" expand="1" optional="1"/>
<field name="quotation_expire" optional="1"/>
<field name="sale_date" optional="0"/>
<field name="party" expand="2"/>
<field name="warehouse" optional="1"/>
+2 -2
View File
@@ -2,9 +2,9 @@
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form/notebook/page[@id='sale']/field[@name='currency']"
position="after">
<xpath expr="//field[@name='sale_date']" position="before">
<label name="price_list"/>
<field name="price_list"/>
<newline/>
</xpath>
</data>
@@ -2,8 +2,7 @@
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form/notebook/page[@id='sale']/field[@name='currency']"
position="after">
<xpath expr="//field[@name='shipping_date']" position="after">
<label name="carrier"/>
<field name="carrier"/>
</xpath>