mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 11:36:44 +00:00
Order start dates (#8966)
* Add 'start_date' field to orders - PurchaseOrder - SalesOrder - ReturnOrder * Add serializer field * Add API filters * Add table columns * Add fields to forms * Table filters * Add validation check * Refactor BuildOrderTable * Update detail page * Bump API version * Allow sorting by start_date * Fix for purchase order field * Update detail pages * Update playwright tests * Updated playwright tests * Documentation updates * Updated playwright tests
This commit is contained in:
parent
0c56a3132b
commit
eee4916350
15
docs/docs/build/build.md
vendored
15
docs/docs/build/build.md
vendored
@ -96,7 +96,7 @@ When a *Build Order* is created, we then have the ability to *allocate* stock it
|
|||||||
!!! info "Example - Stock Allocation"
|
!!! info "Example - Stock Allocation"
|
||||||
Let's say that to assembly a single "Widget", we require 2 "flanges". So, to complete a build of 10 "Widgets", 20 "flanges" will be required. We *allocate* 20 flanged against this build order.
|
Let's say that to assembly a single "Widget", we require 2 "flanges". So, to complete a build of 10 "Widgets", 20 "flanges" will be required. We *allocate* 20 flanged against this build order.
|
||||||
|
|
||||||
Allocating stock to a build does not actually subtrack the stock from the database. Allocations signal an *intent* to take that stock for the purpose of this build. Stock allocations are actioned at the completion of a build.
|
Allocating stock to a build does not actually subtract the stock from the database. Allocations signal an *intent* to take that stock for the purpose of this build. Stock allocations are subtracted from stock at the completion of a build.
|
||||||
|
|
||||||
!!! info "Part Allocation Information"
|
!!! info "Part Allocation Information"
|
||||||
Any part which has stock allocated to a build order will indicate this on the part information page.
|
Any part which has stock allocated to a build order will indicate this on the part information page.
|
||||||
@ -243,7 +243,7 @@ The form will validate the build order is ready to be completed, and will preven
|
|||||||
If you wish to complete the build despite the missing parts, toggle the `Accept Unallocated` option to true to override the warning and allow completion with unallocated parts.
|
If you wish to complete the build despite the missing parts, toggle the `Accept Unallocated` option to true to override the warning and allow completion with unallocated parts.
|
||||||
|
|
||||||
!!! info "Overallocated Stock Items"
|
!!! info "Overallocated Stock Items"
|
||||||
If the warning message `Some stock items have been overallocated` is shown, you have more stock than required by the BOM for the part being built allocated to the build order. By default the `Not permissted` option is selected and you will need to return to the allocation screen and remove the extra items before the build can be completed.
|
If the warning message `Some stock items have been overallocated` is shown, you have more stock than required by the BOM for the part being built allocated to the build order. By default the `Not permitted` option is selected and you will need to return to the allocation screen and remove the extra items before the build can be completed.
|
||||||
|
|
||||||
Alternatively, you can select `Accept as consumed by this build order` to continue with the allocation and remove the extra items from stock (e.g. if they were destroyed during build), or select `Deallocate before completing this build order` if you would like the extra items to be returned to stock for use in future builds.
|
Alternatively, you can select `Accept as consumed by this build order` to continue with the allocation and remove the extra items from stock (e.g. if they were destroyed during build), or select `Deallocate before completing this build order` if you would like the extra items to be returned to stock for use in future builds.
|
||||||
|
|
||||||
@ -265,17 +265,22 @@ The `Cancel Build` form will be displayed, click on the confirmation switch then
|
|||||||
|
|
||||||
## Build Scheduling
|
## Build Scheduling
|
||||||
|
|
||||||
|
Build orders can be scheduled for a future date, to allow for planning of production schedules.
|
||||||
|
|
||||||
### Start Date
|
### Start Date
|
||||||
|
|
||||||
Build orders can be optionally scheduled to *start* at a specified date. This may be useful for planning production schedules.
|
Build orders can be optionally scheduled to *start* at a specified date, by setting the *Start Date* field. This field can be left blank if the build is to start immediately.
|
||||||
|
|
||||||
|
### Target Date
|
||||||
|
|
||||||
|
Build orders can be optionally scheduled to be completed by a certain date, by setting the *Target Date* field. This field can be left blank if the build has no specific deadline.
|
||||||
|
|
||||||
### Overdue Builds
|
### Overdue Builds
|
||||||
|
|
||||||
Build orders may (optionally) have a target completion date specified. If this date is reached but the build order remains incomplete, then the build is considered *overdue*.
|
If the *Target Date* is reached but the build order remains incomplete, then the build is considered *overdue*.
|
||||||
|
|
||||||
This can be useful for tracking production delays, and can be used to generate reports on build order performance.
|
This can be useful for tracking production delays, and can be used to generate reports on build order performance.
|
||||||
|
|
||||||
|
|
||||||
## Build Order Settings
|
## Build Order Settings
|
||||||
|
|
||||||
The following [global settings](../settings/global.md) are available for adjusting the behavior of build orders:
|
The following [global settings](../settings/global.md) are available for adjusting the behavior of build orders:
|
||||||
|
@ -107,19 +107,19 @@ Each item marked as "received" is automatically converted into a stock item.
|
|||||||
|
|
||||||
To see the list of stock items created from the purchase order, click on the <span class="badge inventree nav side"><span class='fas fa-sign-in-alt'></span> Received Items</span> tab.
|
To see the list of stock items created from the purchase order, click on the <span class="badge inventree nav side"><span class='fas fa-sign-in-alt'></span> Received Items</span> tab.
|
||||||
|
|
||||||
### Complete Order
|
## Complete Order
|
||||||
|
|
||||||
Once the quantity of all __received__ items is equal or above the quantity of all line items, the order will be automatically marked as __complete__.
|
Once the quantity of all __received__ items is equal or above the quantity of all line items, the order will be automatically marked as __complete__.
|
||||||
|
|
||||||
It is also possible to complete the order before all items were received (or if there were missing items).
|
It is also possible to complete the order before all items were received (or if there were missing items).
|
||||||
To do so, click on the <span class='fas fa-check-circle'></span> button on the main purchase order detail panel and confirm the order was completed.
|
To do so, click on the <span class='fas fa-check-circle'></span> button on the main purchase order detail panel and confirm the order was completed.
|
||||||
|
|
||||||
### Cancel Order
|
## Cancel Order
|
||||||
|
|
||||||
In the event that the order won't be processed, user has the option of cancelling the order instead.
|
In the event that the order won't be processed, user has the option of cancelling the order instead.
|
||||||
To do so, simply click on the <span class='fas fa-times-circle'></span> button on the main purchase order detail panel and confirm the purchase order has been cancelled.
|
To do so, simply click on the <span class='fas fa-times-circle'></span> button on the main purchase order detail panel and confirm the purchase order has been cancelled.
|
||||||
|
|
||||||
### Duplicate Purchase Order
|
## Duplicate Purchase Order
|
||||||
|
|
||||||
Duplicating a Purchase Order allows the user to quickly create a new *copy* of an existing order, using the same supplier and line item information.
|
Duplicating a Purchase Order allows the user to quickly create a new *copy* of an existing order, using the same supplier and line item information.
|
||||||
|
|
||||||
@ -141,7 +141,23 @@ A new purchase order is then created based on the currently selected order:
|
|||||||
{% include "img.html" %}
|
{% include "img.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
||||||
### Calendar view
|
## Order Scheduling
|
||||||
|
|
||||||
|
Purchase orders can be scheduled for a future date, to allow for planning of future orders.
|
||||||
|
|
||||||
|
### Start Date
|
||||||
|
|
||||||
|
The *Start Date* of the purchase order is the date on which the order is scheduled to be issued to the supplier.
|
||||||
|
|
||||||
|
### Target Date
|
||||||
|
|
||||||
|
The *Target Date* of the purchase order is the date on which the order is expected to be completed / received from the supplier.
|
||||||
|
|
||||||
|
### Overdue Orders
|
||||||
|
|
||||||
|
If the *Target Date* of the purchase order is reached but the order has not been completed, the order will be marked as *overdue*.
|
||||||
|
|
||||||
|
## Calendar view
|
||||||
|
|
||||||
Using the button to the top right of the list of Purchase Orders, the view can be switched to a calendar view using the button <span class='fas fa-calendar-alt'></span>. This view shows orders with a defined target date only.
|
Using the button to the top right of the list of Purchase Orders, the view can be switched to a calendar view using the button <span class='fas fa-calendar-alt'></span>. This view shows orders with a defined target date only.
|
||||||
|
|
||||||
|
@ -115,7 +115,23 @@ While [line items](#line-items) must reference a particular stock item, extra li
|
|||||||
|
|
||||||
Custom [reports](../report/templates.md) can be generated against each Return Order.
|
Custom [reports](../report/templates.md) can be generated against each Return Order.
|
||||||
|
|
||||||
### Calendar view
|
## Order Scheduling
|
||||||
|
|
||||||
|
Return Orders can be scheduled to be completed on a specific date. This can be useful for planning and tracking the return of items.
|
||||||
|
|
||||||
|
### Start Date
|
||||||
|
|
||||||
|
The *Start Date* of the return order is the date on which the order is scheduled to be issued to the customer.
|
||||||
|
|
||||||
|
### Target Date
|
||||||
|
|
||||||
|
The *Target Date* of the return order is the date on which the order is scheduled to be completed.
|
||||||
|
|
||||||
|
### Overdue Orders
|
||||||
|
|
||||||
|
If the *Target Date* of a return order has passed, the order will be marked as *Overdue*. This can be useful for tracking orders which are behind schedule.
|
||||||
|
|
||||||
|
## Calendar view
|
||||||
|
|
||||||
Using the button to the top right of the list of Return Orders, the view can be switched to a calendar view using the button <span class='fas fa-calendar-alt'></span>. This view shows orders with a defined target date only.
|
Using the button to the top right of the list of Return Orders, the view can be switched to a calendar view using the button <span class='fas fa-calendar-alt'></span>. This view shows orders with a defined target date only.
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ Fill out the rest of the form with the sales order information then click on <sp
|
|||||||
|
|
||||||
Each Sales Order is uniquely identified by its *Reference* field. Read more about [reference fields](../settings/reference.md).
|
Each Sales Order is uniquely identified by its *Reference* field. Read more about [reference fields](../settings/reference.md).
|
||||||
|
|
||||||
#### Add Line Items
|
### Add Line Items
|
||||||
|
|
||||||
On the sales order detail page, user can link parts to the sales order selecting the <span class="badge inventree nav side"><span class='fas fa-list-ol'></span> Line Items</span> tab then clicking on the <span class="badge inventree add"><span class='fas fa-plus-circle'></span> Add Line Item</span> button.
|
On the sales order detail page, user can link parts to the sales order selecting the <span class="badge inventree nav side"><span class='fas fa-list-ol'></span> Line Items</span> tab then clicking on the <span class="badge inventree add"><span class='fas fa-plus-circle'></span> Add Line Item</span> button.
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ Once the "Add Line Item" form opens, select a part in the list.
|
|||||||
|
|
||||||
Fill out the rest of the form then click on <span class="badge inventree confirm">Submit</span>
|
Fill out the rest of the form then click on <span class="badge inventree confirm">Submit</span>
|
||||||
|
|
||||||
#### Shipments
|
## Shipments
|
||||||
|
|
||||||
After all line items were added to the sales order, user needs to create one or more [shipments](#sales-order-shipments) in order to allocate stock for those parts.
|
After all line items were added to the sales order, user needs to create one or more [shipments](#sales-order-shipments) in order to allocate stock for those parts.
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ In order to create a new shipment:
|
|||||||
|
|
||||||
Repeat the two steps above to create more shipments.
|
Repeat the two steps above to create more shipments.
|
||||||
|
|
||||||
#### Allocate Stock Items
|
### Allocate Stock Items
|
||||||
|
|
||||||
After shipments were created, user can either:
|
After shipments were created, user can either:
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ After shipments were created, user can either:
|
|||||||
|
|
||||||
During the allocation process, user is required to select the desired shipment that will contain the stock items.
|
During the allocation process, user is required to select the desired shipment that will contain the stock items.
|
||||||
|
|
||||||
#### Complete Shipment
|
### Complete Shipment
|
||||||
|
|
||||||
To complete a shipment, click on the <span class="badge inventree nav side"><span class='fas fa-truck-loading'></span> Pending Shipments</span> tab then click on <span class='fas fa-truck'></span> button shown in the shipment table.
|
To complete a shipment, click on the <span class="badge inventree nav side"><span class='fas fa-truck-loading'></span> Pending Shipments</span> tab then click on <span class='fas fa-truck'></span> button shown in the shipment table.
|
||||||
|
|
||||||
@ -99,16 +99,31 @@ Fill out the "Complete Shipment" form then click on <span class="badge inventree
|
|||||||
|
|
||||||
To view all the completed shipment, click on the <span class="badge inventree nav side"><span class='fas fa-truck'></span> Completed Shipments</span> tab. In the completed shipments table, click on the <span class='fas fa-plus'></span> icon next to each shipment reference to see the items and quantities which were shipped.
|
To view all the completed shipment, click on the <span class="badge inventree nav side"><span class='fas fa-truck'></span> Completed Shipments</span> tab. In the completed shipments table, click on the <span class='fas fa-plus'></span> icon next to each shipment reference to see the items and quantities which were shipped.
|
||||||
|
|
||||||
### Complete Order
|
## Complete Order
|
||||||
|
|
||||||
Once all items in the sales order have been shipped, click on <span class="badge inventree add"><span class='fas fa-check-circle'></span> Complete Order</span> to mark the sales order as shipped. Confirm then click on <span class="badge inventree confirm">Submit</span> to complete the order.
|
Once all items in the sales order have been shipped, click on <span class="badge inventree add"><span class='fas fa-check-circle'></span> Complete Order</span> to mark the sales order as shipped. Confirm then click on <span class="badge inventree confirm">Submit</span> to complete the order.
|
||||||
|
|
||||||
### Cancel Order
|
## Cancel Order
|
||||||
|
|
||||||
To cancel the order, click on the <span class='fas fa-tools'></span> menu button next to the <span class="badge inventree add"><span class='fas fa-check-circle'></span> Complete Order</span> button, then click on the "<span class='fas fa-tools'></span> Cancel Order" menu option. Confirm then click on the <span class="badge inventree confirm">Submit</span> to cancel the order.
|
To cancel the order, click on the <span class='fas fa-tools'></span> menu button next to the <span class="badge inventree add"><span class='fas fa-check-circle'></span> Complete Order</span> button, then click on the "<span class='fas fa-tools'></span> Cancel Order" menu option. Confirm then click on the <span class="badge inventree confirm">Submit</span> to cancel the order.
|
||||||
|
|
||||||
|
## Order Scheduling
|
||||||
|
|
||||||
### Calendar view
|
Sales orders can be scheduled for a future date, to allow for order scheduling.
|
||||||
|
|
||||||
|
### Start Date
|
||||||
|
|
||||||
|
The *Start Date* of the sales order is the date on which the order is scheduled to be issued, allowing work to begin on the order.
|
||||||
|
|
||||||
|
### Target Date
|
||||||
|
|
||||||
|
The *Target Date* of the sales order is the date on which the order is scheduled to be completed and shipped.
|
||||||
|
|
||||||
|
### Overdue Orders
|
||||||
|
|
||||||
|
If the *Target Date* of the sales order has passed, the order will be marked as *overdue*.
|
||||||
|
|
||||||
|
## Calendar view
|
||||||
|
|
||||||
Using the button to the top right of the list of Sales Orders, the view can be switched to a calendar view using the button <span class='fas fa-calendar-alt'></span>. This view shows orders with a defined target date only.
|
Using the button to the top right of the list of Sales Orders, the view can be switched to a calendar view using the button <span class='fas fa-calendar-alt'></span>. This view shows orders with a defined target date only.
|
||||||
|
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
"""InvenTree API version information."""
|
"""InvenTree API version information."""
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 305
|
INVENTREE_API_VERSION = 306
|
||||||
|
|
||||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||||
|
|
||||||
|
|
||||||
INVENTREE_API_TEXT = """
|
INVENTREE_API_TEXT = """
|
||||||
|
|
||||||
|
v3-6 0 2025-01-28 : https://github.com/inventree/InvenTree/pull/8966
|
||||||
|
- Adds "start_date" to PurchasesOrder API
|
||||||
|
- Adds "start_date" to SalesOrder API
|
||||||
|
- Adds "start_date" to ReturnOrder API
|
||||||
|
- Updated API filters
|
||||||
|
|
||||||
v305 - 2025-01-26 : https://github.com/inventree/InvenTree/pull/8950
|
v305 - 2025-01-26 : https://github.com/inventree/InvenTree/pull/8950
|
||||||
- Bug fixes for the SupplierPart API
|
- Bug fixes for the SupplierPart API
|
||||||
- Refactoring for data export via API
|
- Refactoring for data export via API
|
||||||
|
@ -181,6 +181,30 @@ class OrderFilter(rest_filters.FilterSet):
|
|||||||
label=_('Created After'), field_name='creation_date', lookup_expr='gt'
|
label=_('Created After'), field_name='creation_date', lookup_expr='gt'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
has_start_date = rest_filters.BooleanFilter(
|
||||||
|
label=_('Has Start Date'), method='filter_has_start_date'
|
||||||
|
)
|
||||||
|
|
||||||
|
def filter_has_start_date(self, queryset, name, value):
|
||||||
|
"""Filter by whether or not the order has a start date."""
|
||||||
|
return queryset.filter(start_date__isnull=not str2bool(value))
|
||||||
|
|
||||||
|
start_date_before = InvenTreeDateFilter(
|
||||||
|
label=_('Start Date Before'), field_name='start_date', lookup_expr='lt'
|
||||||
|
)
|
||||||
|
|
||||||
|
start_date_after = InvenTreeDateFilter(
|
||||||
|
label=_('Start Date After'), field_name='start_date', lookup_expr='gt'
|
||||||
|
)
|
||||||
|
|
||||||
|
has_target_date = rest_filters.BooleanFilter(
|
||||||
|
label=_('Has Target Date'), method='filter_has_target_date'
|
||||||
|
)
|
||||||
|
|
||||||
|
def filter_has_target_date(self, queryset, name, value):
|
||||||
|
"""Filter by whether or not the order has a target date."""
|
||||||
|
return queryset.filter(target_date__isnull=not str2bool(value))
|
||||||
|
|
||||||
target_date_before = InvenTreeDateFilter(
|
target_date_before = InvenTreeDateFilter(
|
||||||
label=_('Target Date Before'), field_name='target_date', lookup_expr='lt'
|
label=_('Target Date Before'), field_name='target_date', lookup_expr='lt'
|
||||||
)
|
)
|
||||||
@ -336,6 +360,7 @@ class PurchaseOrderList(
|
|||||||
'created_by',
|
'created_by',
|
||||||
'reference',
|
'reference',
|
||||||
'supplier__name',
|
'supplier__name',
|
||||||
|
'start_date',
|
||||||
'target_date',
|
'target_date',
|
||||||
'complete_date',
|
'complete_date',
|
||||||
'line_items',
|
'line_items',
|
||||||
@ -797,6 +822,7 @@ class SalesOrderList(
|
|||||||
'customer__name',
|
'customer__name',
|
||||||
'customer_reference',
|
'customer_reference',
|
||||||
'status',
|
'status',
|
||||||
|
'start_date',
|
||||||
'target_date',
|
'target_date',
|
||||||
'line_items',
|
'line_items',
|
||||||
'shipment_date',
|
'shipment_date',
|
||||||
@ -1383,6 +1409,7 @@ class ReturnOrderList(
|
|||||||
'customer_reference',
|
'customer_reference',
|
||||||
'line_items',
|
'line_items',
|
||||||
'status',
|
'status',
|
||||||
|
'start_date',
|
||||||
'target_date',
|
'target_date',
|
||||||
'complete_date',
|
'complete_date',
|
||||||
'project_code',
|
'project_code',
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 4.2.18 on 2025-01-27 12:50
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('order', '0105_auto_20241128_0431'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='purchaseorder',
|
||||||
|
name='start_date',
|
||||||
|
field=models.DateField(blank=True, help_text='Scheduled start date for this order', null=True, verbose_name='Start date'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='returnorder',
|
||||||
|
name='start_date',
|
||||||
|
field=models.DateField(blank=True, help_text='Scheduled start date for this order', null=True, verbose_name='Start date'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='salesorder',
|
||||||
|
name='start_date',
|
||||||
|
field=models.DateField(blank=True, help_text='Scheduled start date for this order', null=True, verbose_name='Start date'),
|
||||||
|
),
|
||||||
|
]
|
@ -203,6 +203,8 @@ class Order(
|
|||||||
creation_date: Automatic date of order creation
|
creation_date: Automatic date of order creation
|
||||||
created_by: User who created this order (automatically captured)
|
created_by: User who created this order (automatically captured)
|
||||||
issue_date: Date the order was issued
|
issue_date: Date the order was issued
|
||||||
|
start_date: Date the order is scheduled to be started
|
||||||
|
target_date: Expected or desired completion date
|
||||||
complete_date: Date the order was completed
|
complete_date: Date the order was completed
|
||||||
responsible: User (or group) responsible for managing the order
|
responsible: User (or group) responsible for managing the order
|
||||||
"""
|
"""
|
||||||
@ -244,6 +246,13 @@ class Order(
|
|||||||
'contact': _('Contact does not match selected company')
|
'contact': _('Contact does not match selected company')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Target date should be *after* the start date
|
||||||
|
if self.start_date and self.target_date and self.start_date > self.target_date:
|
||||||
|
raise ValidationError({
|
||||||
|
'target_date': _('Target date must be after start date'),
|
||||||
|
'start_date': _('Start date must be before target date'),
|
||||||
|
})
|
||||||
|
|
||||||
def clean_line_item(self, line):
|
def clean_line_item(self, line):
|
||||||
"""Clean a line item for this order.
|
"""Clean a line item for this order.
|
||||||
|
|
||||||
@ -310,6 +319,13 @@ class Order(
|
|||||||
blank=True, verbose_name=_('Link'), help_text=_('Link to external page')
|
blank=True, verbose_name=_('Link'), help_text=_('Link to external page')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
start_date = models.DateField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
verbose_name=_('Start date'),
|
||||||
|
help_text=_('Scheduled start date for this order'),
|
||||||
|
)
|
||||||
|
|
||||||
target_date = models.DateField(
|
target_date = models.DateField(
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
|
@ -186,8 +186,9 @@ class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Seria
|
|||||||
"""Construct a set of fields for this serializer."""
|
"""Construct a set of fields for this serializer."""
|
||||||
return [
|
return [
|
||||||
'pk',
|
'pk',
|
||||||
'creation_date',
|
|
||||||
'created_by',
|
'created_by',
|
||||||
|
'creation_date',
|
||||||
|
'start_date',
|
||||||
'target_date',
|
'target_date',
|
||||||
'description',
|
'description',
|
||||||
'line_items',
|
'line_items',
|
||||||
|
@ -170,6 +170,9 @@ export function usePurchaseOrderFields({
|
|||||||
order_currency: {
|
order_currency: {
|
||||||
icon: <IconCoins />
|
icon: <IconCoins />
|
||||||
},
|
},
|
||||||
|
start_date: {
|
||||||
|
icon: <IconCalendar />
|
||||||
|
},
|
||||||
target_date: {
|
target_date: {
|
||||||
icon: <IconCalendar />
|
icon: <IconCalendar />
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Flex, Table } from '@mantine/core';
|
import { Flex, Table } from '@mantine/core';
|
||||||
import { IconAddressBook, IconUser, IconUsers } from '@tabler/icons-react';
|
import {
|
||||||
|
IconAddressBook,
|
||||||
|
IconCalendar,
|
||||||
|
IconUser,
|
||||||
|
IconUsers
|
||||||
|
} from '@tabler/icons-react';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
import RemoveRowButton from '../components/buttons/RemoveRowButton';
|
import RemoveRowButton from '../components/buttons/RemoveRowButton';
|
||||||
@ -39,7 +44,12 @@ export function useReturnOrderFields({
|
|||||||
customer_reference: {},
|
customer_reference: {},
|
||||||
project_code: {},
|
project_code: {},
|
||||||
order_currency: {},
|
order_currency: {},
|
||||||
target_date: {},
|
start_date: {
|
||||||
|
icon: <IconCalendar />
|
||||||
|
},
|
||||||
|
target_date: {
|
||||||
|
icon: <IconCalendar />
|
||||||
|
},
|
||||||
link: {},
|
link: {},
|
||||||
contact: {
|
contact: {
|
||||||
icon: <IconUser />,
|
icon: <IconUser />,
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Table } from '@mantine/core';
|
import { Table } from '@mantine/core';
|
||||||
import { IconAddressBook, IconUser, IconUsers } from '@tabler/icons-react';
|
import {
|
||||||
|
IconAddressBook,
|
||||||
|
IconCalendar,
|
||||||
|
IconUser,
|
||||||
|
IconUsers
|
||||||
|
} from '@tabler/icons-react';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import RemoveRowButton from '../components/buttons/RemoveRowButton';
|
import RemoveRowButton from '../components/buttons/RemoveRowButton';
|
||||||
@ -40,7 +45,12 @@ export function useSalesOrderFields({
|
|||||||
customer_reference: {},
|
customer_reference: {},
|
||||||
project_code: {},
|
project_code: {},
|
||||||
order_currency: {},
|
order_currency: {},
|
||||||
target_date: {},
|
start_date: {
|
||||||
|
icon: <IconCalendar />
|
||||||
|
},
|
||||||
|
target_date: {
|
||||||
|
icon: <IconCalendar />
|
||||||
|
},
|
||||||
link: {},
|
link: {},
|
||||||
contact: {
|
contact: {
|
||||||
icon: <IconUser />,
|
icon: <IconUser />,
|
||||||
|
@ -186,6 +186,7 @@ export default function BuildDetail() {
|
|||||||
name: 'creation_date',
|
name: 'creation_date',
|
||||||
label: t`Created`,
|
label: t`Created`,
|
||||||
icon: 'calendar',
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
hidden: !build.creation_date
|
hidden: !build.creation_date
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -193,6 +194,7 @@ export default function BuildDetail() {
|
|||||||
name: 'start_date',
|
name: 'start_date',
|
||||||
label: t`Start Date`,
|
label: t`Start Date`,
|
||||||
icon: 'calendar',
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
hidden: !build.start_date
|
hidden: !build.start_date
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -200,6 +202,7 @@ export default function BuildDetail() {
|
|||||||
name: 'target_date',
|
name: 'target_date',
|
||||||
label: t`Target Date`,
|
label: t`Target Date`,
|
||||||
icon: 'calendar',
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
hidden: !build.target_date
|
hidden: !build.target_date
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -207,6 +210,7 @@ export default function BuildDetail() {
|
|||||||
name: 'completion_date',
|
name: 'completion_date',
|
||||||
label: t`Completed`,
|
label: t`Completed`,
|
||||||
icon: 'calendar',
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
hidden: !build.completion_date
|
hidden: !build.completion_date
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -243,6 +243,14 @@ export default function PurchaseOrderDetail() {
|
|||||||
copy: true,
|
copy: true,
|
||||||
hidden: !order.issue_date
|
hidden: !order.issue_date
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
|
name: 'start_date',
|
||||||
|
label: t`Start Date`,
|
||||||
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
|
hidden: !order.start_date
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'date',
|
type: 'date',
|
||||||
name: 'target_date',
|
name: 'target_date',
|
||||||
|
@ -214,6 +214,14 @@ export default function ReturnOrderDetail() {
|
|||||||
copy: true,
|
copy: true,
|
||||||
hidden: !order.issue_date
|
hidden: !order.issue_date
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
|
name: 'start_date',
|
||||||
|
label: t`Start Date`,
|
||||||
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
|
hidden: !order.start_date
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'date',
|
type: 'date',
|
||||||
name: 'target_date',
|
name: 'target_date',
|
||||||
|
@ -225,6 +225,14 @@ export default function SalesOrderDetail() {
|
|||||||
copy: true,
|
copy: true,
|
||||||
hidden: !order.issue_date
|
hidden: !order.issue_date
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
|
name: 'start_date',
|
||||||
|
label: t`Start Date`,
|
||||||
|
icon: 'calendar',
|
||||||
|
hidden: !order.start_date,
|
||||||
|
copy: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'date',
|
type: 'date',
|
||||||
name: 'target_date',
|
name: 'target_date',
|
||||||
|
@ -243,6 +243,14 @@ export function DateColumn(props: TableColumnProps): TableColumn {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function StartDateColumn(props: TableColumnProps): TableColumn {
|
||||||
|
return DateColumn({
|
||||||
|
accessor: 'start_date',
|
||||||
|
title: t`Start Date`,
|
||||||
|
...props
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function TargetDateColumn(props: TableColumnProps): TableColumn {
|
export function TargetDateColumn(props: TableColumnProps): TableColumn {
|
||||||
return DateColumn({
|
return DateColumn({
|
||||||
accessor: 'target_date',
|
accessor: 'target_date',
|
||||||
|
@ -169,6 +169,24 @@ export function CreatedAfterFilter(): TableFilter {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function StartDateBeforeFilter(): TableFilter {
|
||||||
|
return {
|
||||||
|
name: 'start_date_before',
|
||||||
|
label: t`Start Date Before`,
|
||||||
|
description: t`Show items with a start date before this date`,
|
||||||
|
type: 'date'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StartDateAfterFilter(): TableFilter {
|
||||||
|
return {
|
||||||
|
name: 'start_date_after',
|
||||||
|
label: t`Start Date After`,
|
||||||
|
description: t`Show items with a start date after this date`,
|
||||||
|
type: 'date'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function TargetDateBeforeFilter(): TableFilter {
|
export function TargetDateBeforeFilter(): TableFilter {
|
||||||
return {
|
return {
|
||||||
name: 'target_date_before',
|
name: 'target_date_before',
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
ProjectCodeColumn,
|
ProjectCodeColumn,
|
||||||
ReferenceColumn,
|
ReferenceColumn,
|
||||||
ResponsibleColumn,
|
ResponsibleColumn,
|
||||||
|
StartDateColumn,
|
||||||
StatusColumn,
|
StatusColumn,
|
||||||
TargetDateColumn
|
TargetDateColumn
|
||||||
} from '../ColumnRenderers';
|
} from '../ColumnRenderers';
|
||||||
@ -43,6 +44,8 @@ import {
|
|||||||
OverdueFilter,
|
OverdueFilter,
|
||||||
ProjectCodeFilter,
|
ProjectCodeFilter,
|
||||||
ResponsibleFilter,
|
ResponsibleFilter,
|
||||||
|
StartDateAfterFilter,
|
||||||
|
StartDateBeforeFilter,
|
||||||
type TableFilter,
|
type TableFilter,
|
||||||
TargetDateAfterFilter,
|
TargetDateAfterFilter,
|
||||||
TargetDateBeforeFilter
|
TargetDateBeforeFilter
|
||||||
@ -107,11 +110,7 @@ export function BuildOrderTable({
|
|||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
CreationDateColumn({}),
|
CreationDateColumn({}),
|
||||||
DateColumn({
|
StartDateColumn({}),
|
||||||
accessor: 'start_date',
|
|
||||||
title: t`Start Date`,
|
|
||||||
sortable: true
|
|
||||||
}),
|
|
||||||
TargetDateColumn({}),
|
TargetDateColumn({}),
|
||||||
DateColumn({
|
DateColumn({
|
||||||
accessor: 'completion_date',
|
accessor: 'completion_date',
|
||||||
@ -156,18 +155,8 @@ export function BuildOrderTable({
|
|||||||
CreatedAfterFilter(),
|
CreatedAfterFilter(),
|
||||||
TargetDateBeforeFilter(),
|
TargetDateBeforeFilter(),
|
||||||
TargetDateAfterFilter(),
|
TargetDateAfterFilter(),
|
||||||
{
|
StartDateBeforeFilter(),
|
||||||
name: 'start_date_before',
|
StartDateAfterFilter(),
|
||||||
type: 'date',
|
|
||||||
label: t`Start Date Before`,
|
|
||||||
description: t`Show items with a start date before this date`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'start_date_after',
|
|
||||||
type: 'date',
|
|
||||||
label: t`Start Date After`,
|
|
||||||
description: t`Show items with a start date after this date`
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'has_target_date',
|
name: 'has_target_date',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
ProjectCodeColumn,
|
ProjectCodeColumn,
|
||||||
ReferenceColumn,
|
ReferenceColumn,
|
||||||
ResponsibleColumn,
|
ResponsibleColumn,
|
||||||
|
StartDateColumn,
|
||||||
StatusColumn,
|
StatusColumn,
|
||||||
TargetDateColumn
|
TargetDateColumn
|
||||||
} from '../ColumnRenderers';
|
} from '../ColumnRenderers';
|
||||||
@ -44,6 +45,8 @@ import {
|
|||||||
OverdueFilter,
|
OverdueFilter,
|
||||||
ProjectCodeFilter,
|
ProjectCodeFilter,
|
||||||
ResponsibleFilter,
|
ResponsibleFilter,
|
||||||
|
StartDateAfterFilter,
|
||||||
|
StartDateBeforeFilter,
|
||||||
type TableFilter,
|
type TableFilter,
|
||||||
TargetDateAfterFilter,
|
TargetDateAfterFilter,
|
||||||
TargetDateBeforeFilter
|
TargetDateBeforeFilter
|
||||||
@ -79,6 +82,20 @@ export function PurchaseOrderTable({
|
|||||||
CreatedAfterFilter(),
|
CreatedAfterFilter(),
|
||||||
TargetDateBeforeFilter(),
|
TargetDateBeforeFilter(),
|
||||||
TargetDateAfterFilter(),
|
TargetDateAfterFilter(),
|
||||||
|
StartDateBeforeFilter(),
|
||||||
|
StartDateAfterFilter(),
|
||||||
|
{
|
||||||
|
name: 'has_target_date',
|
||||||
|
type: 'boolean',
|
||||||
|
label: t`Has Target Date`,
|
||||||
|
description: t`Show orders with a target date`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'has_start_date',
|
||||||
|
type: 'boolean',
|
||||||
|
label: t`Has Start Date`,
|
||||||
|
description: t`Show orders with a start date`
|
||||||
|
},
|
||||||
CompletedBeforeFilter(),
|
CompletedBeforeFilter(),
|
||||||
CompletedAfterFilter(),
|
CompletedAfterFilter(),
|
||||||
ProjectCodeFilter({ choices: projectCodeFilters.choices }),
|
ProjectCodeFilter({ choices: projectCodeFilters.choices }),
|
||||||
@ -120,6 +137,7 @@ export function PurchaseOrderTable({
|
|||||||
ProjectCodeColumn({}),
|
ProjectCodeColumn({}),
|
||||||
CreationDateColumn({}),
|
CreationDateColumn({}),
|
||||||
CreatedByColumn({}),
|
CreatedByColumn({}),
|
||||||
|
StartDateColumn({}),
|
||||||
TargetDateColumn({}),
|
TargetDateColumn({}),
|
||||||
CompletionDateColumn({
|
CompletionDateColumn({
|
||||||
accessor: 'complete_date'
|
accessor: 'complete_date'
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
ProjectCodeColumn,
|
ProjectCodeColumn,
|
||||||
ReferenceColumn,
|
ReferenceColumn,
|
||||||
ResponsibleColumn,
|
ResponsibleColumn,
|
||||||
|
StartDateColumn,
|
||||||
StatusColumn,
|
StatusColumn,
|
||||||
TargetDateColumn
|
TargetDateColumn
|
||||||
} from '../ColumnRenderers';
|
} from '../ColumnRenderers';
|
||||||
@ -44,6 +45,8 @@ import {
|
|||||||
OverdueFilter,
|
OverdueFilter,
|
||||||
ProjectCodeFilter,
|
ProjectCodeFilter,
|
||||||
ResponsibleFilter,
|
ResponsibleFilter,
|
||||||
|
StartDateAfterFilter,
|
||||||
|
StartDateBeforeFilter,
|
||||||
type TableFilter,
|
type TableFilter,
|
||||||
TargetDateAfterFilter,
|
TargetDateAfterFilter,
|
||||||
TargetDateBeforeFilter
|
TargetDateBeforeFilter
|
||||||
@ -76,6 +79,20 @@ export function ReturnOrderTable({
|
|||||||
CreatedAfterFilter(),
|
CreatedAfterFilter(),
|
||||||
TargetDateBeforeFilter(),
|
TargetDateBeforeFilter(),
|
||||||
TargetDateAfterFilter(),
|
TargetDateAfterFilter(),
|
||||||
|
StartDateBeforeFilter(),
|
||||||
|
StartDateAfterFilter(),
|
||||||
|
{
|
||||||
|
name: 'has_target_date',
|
||||||
|
type: 'boolean',
|
||||||
|
label: t`Has Target Date`,
|
||||||
|
description: t`Show orders with a target date`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'has_start_date',
|
||||||
|
type: 'boolean',
|
||||||
|
label: t`Has Start Date`,
|
||||||
|
description: t`Show orders with a start date`
|
||||||
|
},
|
||||||
CompletedBeforeFilter(),
|
CompletedBeforeFilter(),
|
||||||
CompletedAfterFilter(),
|
CompletedAfterFilter(),
|
||||||
HasProjectCodeFilter(),
|
HasProjectCodeFilter(),
|
||||||
@ -129,6 +146,7 @@ export function ReturnOrderTable({
|
|||||||
ProjectCodeColumn({}),
|
ProjectCodeColumn({}),
|
||||||
CreationDateColumn({}),
|
CreationDateColumn({}),
|
||||||
CreatedByColumn({}),
|
CreatedByColumn({}),
|
||||||
|
StartDateColumn({}),
|
||||||
TargetDateColumn({}),
|
TargetDateColumn({}),
|
||||||
CompletionDateColumn({
|
CompletionDateColumn({
|
||||||
accessor: 'complete_date'
|
accessor: 'complete_date'
|
||||||
|
@ -27,6 +27,7 @@ import {
|
|||||||
ReferenceColumn,
|
ReferenceColumn,
|
||||||
ResponsibleColumn,
|
ResponsibleColumn,
|
||||||
ShipmentDateColumn,
|
ShipmentDateColumn,
|
||||||
|
StartDateColumn,
|
||||||
StatusColumn,
|
StatusColumn,
|
||||||
TargetDateColumn
|
TargetDateColumn
|
||||||
} from '../ColumnRenderers';
|
} from '../ColumnRenderers';
|
||||||
@ -45,6 +46,8 @@ import {
|
|||||||
OverdueFilter,
|
OverdueFilter,
|
||||||
ProjectCodeFilter,
|
ProjectCodeFilter,
|
||||||
ResponsibleFilter,
|
ResponsibleFilter,
|
||||||
|
StartDateAfterFilter,
|
||||||
|
StartDateBeforeFilter,
|
||||||
type TableFilter,
|
type TableFilter,
|
||||||
TargetDateAfterFilter,
|
TargetDateAfterFilter,
|
||||||
TargetDateBeforeFilter
|
TargetDateBeforeFilter
|
||||||
@ -77,6 +80,20 @@ export function SalesOrderTable({
|
|||||||
CreatedAfterFilter(),
|
CreatedAfterFilter(),
|
||||||
TargetDateBeforeFilter(),
|
TargetDateBeforeFilter(),
|
||||||
TargetDateAfterFilter(),
|
TargetDateAfterFilter(),
|
||||||
|
StartDateBeforeFilter(),
|
||||||
|
StartDateAfterFilter(),
|
||||||
|
{
|
||||||
|
name: 'has_target_date',
|
||||||
|
type: 'boolean',
|
||||||
|
label: t`Has Target Date`,
|
||||||
|
description: t`Show orders with a target date`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'has_start_date',
|
||||||
|
type: 'boolean',
|
||||||
|
label: t`Has Start Date`,
|
||||||
|
description: t`Show orders with a start date`
|
||||||
|
},
|
||||||
CompletedBeforeFilter(),
|
CompletedBeforeFilter(),
|
||||||
CompletedAfterFilter(),
|
CompletedAfterFilter(),
|
||||||
HasProjectCodeFilter(),
|
HasProjectCodeFilter(),
|
||||||
@ -166,6 +183,7 @@ export function SalesOrderTable({
|
|||||||
ProjectCodeColumn({}),
|
ProjectCodeColumn({}),
|
||||||
CreationDateColumn({}),
|
CreationDateColumn({}),
|
||||||
CreatedByColumn({}),
|
CreatedByColumn({}),
|
||||||
|
StartDateColumn({}),
|
||||||
TargetDateColumn({}),
|
TargetDateColumn({}),
|
||||||
ShipmentDateColumn({}),
|
ShipmentDateColumn({}),
|
||||||
ResponsibleColumn({}),
|
ResponsibleColumn({}),
|
||||||
|
@ -3,11 +3,12 @@ import { baseUrl } from '../defaults.ts';
|
|||||||
import {
|
import {
|
||||||
clearTableFilters,
|
clearTableFilters,
|
||||||
clickButtonIfVisible,
|
clickButtonIfVisible,
|
||||||
openFilterDrawer
|
openFilterDrawer,
|
||||||
|
setTableChoiceFilter
|
||||||
} from '../helpers.ts';
|
} from '../helpers.ts';
|
||||||
import { doQuickLogin } from '../login.ts';
|
import { doQuickLogin } from '../login.ts';
|
||||||
|
|
||||||
test('Purchase Orders', async ({ page }) => {
|
test('Purchase Orders - List', async ({ page }) => {
|
||||||
await doQuickLogin(page);
|
await doQuickLogin(page);
|
||||||
|
|
||||||
await page.getByRole('tab', { name: 'Purchasing' }).click();
|
await page.getByRole('tab', { name: 'Purchasing' }).click();
|
||||||
@ -22,10 +23,17 @@ test('Purchase Orders', async ({ page }) => {
|
|||||||
await page.getByText('Pending').first().waitFor();
|
await page.getByText('Pending').first().waitFor();
|
||||||
await page.getByText('On Hold').first().waitFor();
|
await page.getByText('On Hold').first().waitFor();
|
||||||
|
|
||||||
// Click through to a particular purchase order
|
// Filter by 'has start date'
|
||||||
await page.getByRole('cell', { name: 'PO0013' }).click();
|
await setTableChoiceFilter(page, 'Has Start Date', 'Yes');
|
||||||
|
await page.getByRole('cell', { name: 'Scheduled purchase order' }).waitFor();
|
||||||
|
|
||||||
|
// Click through to a particular purchase order
|
||||||
|
await page.getByRole('cell', { name: 'PO0015' }).click();
|
||||||
await page.getByRole('button', { name: 'Issue Order' }).waitFor();
|
await page.getByRole('button', { name: 'Issue Order' }).waitFor();
|
||||||
|
|
||||||
|
// Expected values
|
||||||
|
await page.getByText('2025-06-12').waitFor(); // Start Date
|
||||||
|
await page.getByText('2025-07-17').waitFor(); // Target Date
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Purchase Orders - Barcodes', async ({ page }) => {
|
test('Purchase Orders - Barcodes', async ({ page }) => {
|
||||||
@ -70,7 +78,7 @@ test('Purchase Orders - Barcodes', async ({ page }) => {
|
|||||||
await page.getByRole('button', { name: 'Issue Order' }).waitFor();
|
await page.getByRole('button', { name: 'Issue Order' }).waitFor();
|
||||||
|
|
||||||
// Ensure we can scan back to this page, with the associated barcode
|
// Ensure we can scan back to this page, with the associated barcode
|
||||||
await page.goto(`${baseUrl}/`);
|
await page.getByRole('tab', { name: 'Sales' }).click();
|
||||||
await page.waitForTimeout(250);
|
await page.waitForTimeout(250);
|
||||||
await page.getByRole('button', { name: 'Open Barcode Scanner' }).click();
|
await page.getByRole('button', { name: 'Open Barcode Scanner' }).click();
|
||||||
await page.getByPlaceholder('Enter barcode data').fill('1234567890');
|
await page.getByPlaceholder('Enter barcode data').fill('1234567890');
|
||||||
|
@ -33,6 +33,7 @@ test('Tables - Filters', async ({ page }) => {
|
|||||||
await setTableChoiceFilter(page, 'Responsible', 'readers');
|
await setTableChoiceFilter(page, 'Responsible', 'readers');
|
||||||
await setTableChoiceFilter(page, 'Assigned to me', 'No');
|
await setTableChoiceFilter(page, 'Assigned to me', 'No');
|
||||||
await setTableChoiceFilter(page, 'Project Code', 'PRO-ZEN');
|
await setTableChoiceFilter(page, 'Project Code', 'PRO-ZEN');
|
||||||
|
await setTableChoiceFilter(page, 'Has Start Date', 'Yes');
|
||||||
|
|
||||||
await clearTableFilters(page);
|
await clearTableFilters(page);
|
||||||
});
|
});
|
||||||
@ -49,4 +50,17 @@ test('Tables - Columns', async ({ page }) => {
|
|||||||
// De-select some items
|
// De-select some items
|
||||||
await page.getByRole('menuitem', { name: 'Description' }).click();
|
await page.getByRole('menuitem', { name: 'Description' }).click();
|
||||||
await page.getByRole('menuitem', { name: 'Stocktake' }).click();
|
await page.getByRole('menuitem', { name: 'Stocktake' }).click();
|
||||||
|
await page.keyboard.press('Escape');
|
||||||
|
|
||||||
|
await page.goto(`${baseUrl}/sales/index/salesorders`);
|
||||||
|
|
||||||
|
// Open column selector
|
||||||
|
await page.getByLabel('table-select-columns').click();
|
||||||
|
|
||||||
|
await page.getByRole('menuitem', { name: 'Start Date' }).click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Target Date' }).click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Reference', exact: true }).click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Project Code' }).click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user