Purchase orders
This commit is contained in:
parent
35af9889bc
commit
d06e06c413
|
|
@ -579,9 +579,11 @@ abstract class CompanyEntity extends Object
|
||||||
);
|
);
|
||||||
|
|
||||||
bool isModuleEnabled(EntityType entityType) {
|
bool isModuleEnabled(EntityType entityType) {
|
||||||
|
/*
|
||||||
if (entityType == EntityType.purchaseOrder) {
|
if (entityType == EntityType.purchaseOrder) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if ((entityType == EntityType.invoice ||
|
if ((entityType == EntityType.invoice ||
|
||||||
entityType == EntityType.payment) &&
|
entityType == EntityType.payment) &&
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,33 @@ class RestorePurchaseOrdersFailure implements StopSaving {
|
||||||
final List<InvoiceEntity> purchaseOrders;
|
final List<InvoiceEntity> purchaseOrders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EmailPurchaseOrderRequest implements StartSaving {
|
||||||
|
EmailPurchaseOrderRequest(
|
||||||
|
{this.completer,
|
||||||
|
this.purchaseOrderId,
|
||||||
|
this.template,
|
||||||
|
this.subject,
|
||||||
|
this.body});
|
||||||
|
|
||||||
|
final Completer completer;
|
||||||
|
final String purchaseOrderId;
|
||||||
|
final EmailTemplate template;
|
||||||
|
final String subject;
|
||||||
|
final String body;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmailPurchaseOrderSuccess implements StopSaving, PersistData {
|
||||||
|
EmailPurchaseOrderSuccess(this.quote);
|
||||||
|
|
||||||
|
final InvoiceEntity quote;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmailPurchaseOrderFailure implements StopSaving {
|
||||||
|
EmailPurchaseOrderFailure(this.error);
|
||||||
|
|
||||||
|
final dynamic error;
|
||||||
|
}
|
||||||
|
|
||||||
class FilterPurchaseOrders implements PersistUI {
|
class FilterPurchaseOrders implements PersistUI {
|
||||||
FilterPurchaseOrders(this.filter);
|
FilterPurchaseOrders(this.filter);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,12 @@ import 'package:flutter/material.dart';
|
||||||
// Package imports:
|
// Package imports:
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/app_title_bar.dart';
|
import 'package:invoiceninja_flutter/ui/app/app_title_bar.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/purchase_order/edit/purchase_order_edit_vm.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/purchase_order/purchase_order_email_vm.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/purchase_order/purchase_order_pdf_vm.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/purchase_order/purchase_order_screen.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/purchase_order/purchase_order_screen_vm.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/purchase_order/view/purchase_order_view_vm.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/settings/payment_settings_vm.dart';
|
import 'package:invoiceninja_flutter/ui/settings/payment_settings_vm.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||||
import 'package:redux/redux.dart';
|
import 'package:redux/redux.dart';
|
||||||
|
|
@ -169,6 +175,12 @@ class MainScreen extends StatelessWidget {
|
||||||
editingFilterEntity: editingFilterEntity,
|
editingFilterEntity: editingFilterEntity,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case PurchaseOrderScreen.route:
|
||||||
|
screen = EntityScreens(
|
||||||
|
entityType: EntityType.purchaseOrder,
|
||||||
|
editingFilterEntity: editingFilterEntity,
|
||||||
|
);
|
||||||
|
break;
|
||||||
case ProjectScreen.route:
|
case ProjectScreen.route:
|
||||||
screen = EntityScreens(
|
screen = EntityScreens(
|
||||||
entityType: EntityType.project,
|
entityType: EntityType.project,
|
||||||
|
|
@ -392,6 +404,13 @@ class EntityScreens extends StatelessWidget {
|
||||||
? CreditEmailScreen()
|
? CreditEmailScreen()
|
||||||
: CreditEditScreen();
|
: CreditEditScreen();
|
||||||
break;
|
break;
|
||||||
|
case PurchaseOrderScreen.route:
|
||||||
|
child = isPdf
|
||||||
|
? PurchaseOrderPdfScreen()
|
||||||
|
: isEmail
|
||||||
|
? PurchaseOrderEmailScreen()
|
||||||
|
: PurchaseOrderEditScreen();
|
||||||
|
break;
|
||||||
case RecurringInvoiceScreen.route:
|
case RecurringInvoiceScreen.route:
|
||||||
child = isPdf
|
child = isPdf
|
||||||
? RecurringInvoicePdfScreen()
|
? RecurringInvoicePdfScreen()
|
||||||
|
|
@ -447,6 +466,9 @@ class EntityScreens extends StatelessWidget {
|
||||||
case EntityType.credit:
|
case EntityType.credit:
|
||||||
child = CreditEditScreen();
|
child = CreditEditScreen();
|
||||||
break;
|
break;
|
||||||
|
case EntityType.purchaseOrder:
|
||||||
|
child = PurchaseOrderEditScreen();
|
||||||
|
break;
|
||||||
case EntityType.project:
|
case EntityType.project:
|
||||||
child = ProjectEditScreen();
|
child = ProjectEditScreen();
|
||||||
break;
|
break;
|
||||||
|
|
@ -497,6 +519,9 @@ class EntityScreens extends StatelessWidget {
|
||||||
case EntityType.credit:
|
case EntityType.credit:
|
||||||
child = CreditViewScreen();
|
child = CreditViewScreen();
|
||||||
break;
|
break;
|
||||||
|
case EntityType.purchaseOrder:
|
||||||
|
child = PurchaseOrderViewScreen();
|
||||||
|
break;
|
||||||
case EntityType.project:
|
case EntityType.project:
|
||||||
child = ProjectViewScreen();
|
child = ProjectViewScreen();
|
||||||
break;
|
break;
|
||||||
|
|
@ -562,6 +587,11 @@ class EntityScreens extends StatelessWidget {
|
||||||
? CreditViewScreen()
|
? CreditViewScreen()
|
||||||
: CreditViewScreen(isFilter: true);
|
: CreditViewScreen(isFilter: true);
|
||||||
break;
|
break;
|
||||||
|
case EntityType.purchaseOrder:
|
||||||
|
leftFilterChild = editingFilterEntity && !uiState.isEditing
|
||||||
|
? PurchaseOrderViewScreen()
|
||||||
|
: PurchaseOrderViewScreen(isFilter: true);
|
||||||
|
break;
|
||||||
case EntityType.payment:
|
case EntityType.payment:
|
||||||
leftFilterChild = editingFilterEntity && !uiState.isEditing
|
leftFilterChild = editingFilterEntity && !uiState.isEditing
|
||||||
? PaymentEditScreen()
|
? PaymentEditScreen()
|
||||||
|
|
@ -650,6 +680,9 @@ class EntityScreens extends StatelessWidget {
|
||||||
case EntityType.credit:
|
case EntityType.credit:
|
||||||
listWidget = CreditScreenBuilder();
|
listWidget = CreditScreenBuilder();
|
||||||
break;
|
break;
|
||||||
|
case EntityType.purchaseOrder:
|
||||||
|
listWidget = PurchaseOrderScreenBuilder();
|
||||||
|
break;
|
||||||
case EntityType.project:
|
case EntityType.project:
|
||||||
listWidget = ProjectScreenBuilder();
|
listWidget = ProjectScreenBuilder();
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
// Flutter imports:
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
// Package imports:
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
|
||||||
|
// Project imports:
|
||||||
|
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/purchase_order/purchase_order_actions.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/app/invoice/invoice_email_view.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/invoice/invoice_email_vm.dart';
|
||||||
|
import 'package:invoiceninja_flutter/utils/completers.dart';
|
||||||
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||||
|
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||||
|
|
||||||
|
class PurchaseOrderEmailScreen extends StatelessWidget {
|
||||||
|
const PurchaseOrderEmailScreen({Key key}) : super(key: key);
|
||||||
|
|
||||||
|
static const String route = '/purchase_order/email';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return StoreConnector<AppState, EmailPurchaseOrderVM>(
|
||||||
|
onInit: (Store<AppState> store) {
|
||||||
|
final state = store.state;
|
||||||
|
final purchaseOrderId = state.uiState.purchaseOrderUIState.selectedId;
|
||||||
|
final purchaseOrder = state.purchaseOrderState.map[purchaseOrderId];
|
||||||
|
final client = state.clientState.map[purchaseOrder.clientId];
|
||||||
|
if (client.isStale) {
|
||||||
|
store.dispatch(LoadClient(clientId: client.id));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
converter: (Store<AppState> store) {
|
||||||
|
final state = store.state;
|
||||||
|
final purchaseOrderId = state.uiState.purchaseOrderUIState.selectedId;
|
||||||
|
final purchaseOrder = state.purchaseOrderState.map[purchaseOrderId];
|
||||||
|
return EmailPurchaseOrderVM.fromStore(store, purchaseOrder);
|
||||||
|
},
|
||||||
|
builder: (context, viewModel) {
|
||||||
|
return InvoiceEmailView(
|
||||||
|
viewModel: viewModel,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmailPurchaseOrderVM extends EmailEntityVM {
|
||||||
|
EmailPurchaseOrderVM({
|
||||||
|
@required AppState state,
|
||||||
|
@required bool isLoading,
|
||||||
|
@required bool isSaving,
|
||||||
|
@required CompanyEntity company,
|
||||||
|
@required InvoiceEntity invoice,
|
||||||
|
@required ClientEntity client,
|
||||||
|
@required
|
||||||
|
Function(BuildContext, EmailTemplate, String, String) onSendPressed,
|
||||||
|
}) : super(
|
||||||
|
state: state,
|
||||||
|
isLoading: isLoading,
|
||||||
|
isSaving: isSaving,
|
||||||
|
company: company,
|
||||||
|
invoice: invoice,
|
||||||
|
client: client,
|
||||||
|
onSendPressed: onSendPressed,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory EmailPurchaseOrderVM.fromStore(
|
||||||
|
Store<AppState> store, InvoiceEntity purchaseOrder) {
|
||||||
|
final state = store.state;
|
||||||
|
|
||||||
|
return EmailPurchaseOrderVM(
|
||||||
|
state: state,
|
||||||
|
isLoading: state.isLoading,
|
||||||
|
isSaving: state.isSaving,
|
||||||
|
company: state.company,
|
||||||
|
invoice: purchaseOrder,
|
||||||
|
client: state.clientState.map[purchaseOrder.clientId],
|
||||||
|
onSendPressed: (context, template, subject, body) {
|
||||||
|
final completer = snackBarCompleter<Null>(
|
||||||
|
context, AppLocalization.of(context).emailedPurchaseOrder,
|
||||||
|
shouldPop: isMobile(context));
|
||||||
|
if (!isMobile(context)) {
|
||||||
|
completer.future.then((value) {
|
||||||
|
viewEntity(entity: purchaseOrder);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
store.dispatch(EmailPurchaseOrderRequest(
|
||||||
|
completer: completer,
|
||||||
|
purchaseOrderId: purchaseOrder.id,
|
||||||
|
template: template,
|
||||||
|
subject: subject,
|
||||||
|
body: body,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
// Flutter imports:
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
// Package imports:
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
|
||||||
|
// Project imports:
|
||||||
|
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/invoice/invoice_pdf.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/invoice/invoice_pdf_vm.dart';
|
||||||
|
|
||||||
|
class PurchaseOrderPdfScreen extends StatelessWidget {
|
||||||
|
const PurchaseOrderPdfScreen({Key key, this.showAppBar = true})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
final bool showAppBar;
|
||||||
|
|
||||||
|
static const String route = '/purchase_order/pdf';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return StoreConnector<AppState, PurchaseOrderPdfVM>(
|
||||||
|
converter: (Store<AppState> store) {
|
||||||
|
return PurchaseOrderPdfVM.fromStore(store);
|
||||||
|
},
|
||||||
|
builder: (context, vm) {
|
||||||
|
return InvoicePdfView(
|
||||||
|
key: ValueKey('__purchase_order_pdf_${vm.invoice.id}__'),
|
||||||
|
viewModel: vm,
|
||||||
|
showAppBar: showAppBar,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PurchaseOrderPdfVM extends EntityPdfVM {
|
||||||
|
PurchaseOrderPdfVM({
|
||||||
|
AppState state,
|
||||||
|
InvoiceEntity invoice,
|
||||||
|
String activityId,
|
||||||
|
}) : super(
|
||||||
|
state: state,
|
||||||
|
invoice: invoice,
|
||||||
|
activityId: activityId,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory PurchaseOrderPdfVM.fromStore(Store<AppState> store) {
|
||||||
|
final state = store.state;
|
||||||
|
final purchaseOrderUIState = state.uiState.purchaseOrderUIState;
|
||||||
|
final invoiceId = purchaseOrderUIState.selectedId;
|
||||||
|
final invoice = state.purchaseOrderState.get(invoiceId);
|
||||||
|
|
||||||
|
return PurchaseOrderPdfVM(
|
||||||
|
state: state,
|
||||||
|
invoice: invoice,
|
||||||
|
//activityId: purchaseOrderUIState.historyActivityId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,9 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
||||||
static final Map<String, Map<String, String>> _localizedValues = {
|
static final Map<String, Map<String, String>> _localizedValues = {
|
||||||
'en': {
|
'en': {
|
||||||
// STARTER: lang key - do not remove comment
|
// STARTER: lang key - do not remove comment
|
||||||
|
'emailed_purchase_order': 'Successfully queued purchase order to be sent',
|
||||||
|
'emailed_purchase_orders':
|
||||||
|
'Successfully queued purchase orders to be sent',
|
||||||
'enable_react_app': 'Change to the React web app',
|
'enable_react_app': 'Change to the React web app',
|
||||||
'purchase_order_design': 'Purchase Order Design',
|
'purchase_order_design': 'Purchase Order Design',
|
||||||
'purchase_order_terms': 'Purchase Order Terms',
|
'purchase_order_terms': 'Purchase Order Terms',
|
||||||
|
|
@ -70688,6 +70691,14 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
||||||
_localizedValues[localeCode]['enable_react_app'] ??
|
_localizedValues[localeCode]['enable_react_app'] ??
|
||||||
_localizedValues['en']['enable_react_app'];
|
_localizedValues['en']['enable_react_app'];
|
||||||
|
|
||||||
|
String get emailedPurchaseOrder =>
|
||||||
|
_localizedValues[localeCode]['emailed_purchase_orderk'] ??
|
||||||
|
_localizedValues['en']['emailed_purchase_order'];
|
||||||
|
|
||||||
|
String get emailedPurchaseOrders =>
|
||||||
|
_localizedValues[localeCode]['emailed_purchase_orders'] ??
|
||||||
|
_localizedValues['en']['emailed_purchase_orders'];
|
||||||
|
|
||||||
// STARTER: lang field - do not remove comment
|
// STARTER: lang field - do not remove comment
|
||||||
|
|
||||||
String lookup(String key) {
|
String lookup(String key) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue