Skip to content

Commit 81bf3a4

Browse files
committed
Merge remote-tracking branch 'origin/develop' into issue/93-stores-manager-improvements
2 parents fcb939f + 21f5559 commit 81bf3a4

File tree

19 files changed

+438
-125
lines changed

19 files changed

+438
-125
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
## Build generated
66
build/
77
DerivedData/
8-
DerivedSources/
8+
WooCommerce/DerivedSources/
99

1010
## Various settings
1111
*.pbxuser

Podfile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
source 'https://github.com/CocoaPods/Specs.git'
2-
31
inhibit_all_warnings!
42
use_frameworks!
53

Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,6 @@ SPEC CHECKSUMS:
137137
WordPressUI: f2348649b63b5a9392a72b1d2f46dd1d72e80ad9
138138
wpxmlrpc: bfc572f62ce7ee897f6f38b098d2ba08732ecef4
139139

140-
PODFILE CHECKSUM: 1b3a8db08db7d0827c6bad2b1ed8dc6ea93041f4
140+
PODFILE CHECKSUM: b0058ebc467be802babc234b85e02282da5d9d42
141141

142142
COCOAPODS: 1.5.3

WooCommerce/Classes/Authentication/Prologue/LoginPrologueViewController.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ private extension LoginPrologueViewController {
7070
}
7171

7272
func setupUpperLabel() {
73-
upperLabel.text = NSLocalizedString("Check your WooCommerce store on the go, fulfill your orders and get notifications of new sales.", comment: "Login Prologue Legend")
73+
upperLabel.text = NSLocalizedString("Your WooCommerce store on the go. Check your sales, fulfill your orders, and get notifications of new sales.", comment: "Login Prologue Legend")
7474
upperLabel.font = UIFont.font(forStyle: .subheadline, weight: .bold)
7575
upperLabel.textColor = .white
7676
}
@@ -135,19 +135,23 @@ private extension LoginPrologueViewController {
135135
/// Returns the Disclaimer Attributed Text (which contains a link to the Jetpack Setup URL).
136136
///
137137
var disclaimerAttributedText: NSAttributedString {
138-
let disclaimerText = NSLocalizedString("This app requires Jetpack to be able to connect to your WooCommerce Store.\nFor configuration instructions, ", comment: "Login Disclaimer Text")
138+
let disclaimerText = NSLocalizedString("This app requires Jetpack to be able to connect to your WooCommerce Store.\nRead the ", comment: "Login Disclaimer Text and Jetpack config instructions")
139139
let disclaimerAttributes: [NSAttributedStringKey: Any] = [
140140
.font: UIFont.font(forStyle: .caption1, weight: .thin),
141141
.foregroundColor: UIColor.black
142142
]
143143

144-
let readText = NSLocalizedString("read here.", comment: "Login Disclaimer Linked Text")
144+
let readText = NSLocalizedString("configuration instructions", comment: "Login Disclaimer Linked Text")
145145
var readAttributes = disclaimerAttributes
146146
readAttributes[.link] = URL(string: WooConstants.jetpackSetupUrl)
147-
148147
let readAttrText = NSMutableAttributedString(string: readText, attributes: readAttributes)
148+
149+
let endSentenceText = "."
150+
let endSentenceAttrText = NSMutableAttributedString(string: endSentenceText, attributes: disclaimerAttributes)
151+
149152
let disclaimerAttrText = NSMutableAttributedString(string: disclaimerText, attributes: disclaimerAttributes)
150153
disclaimerAttrText.append(readAttrText)
154+
disclaimerAttrText.append(endSentenceAttrText)
151155

152156
return disclaimerAttrText
153157
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Foundation
2+
3+
/// DateFormatter Extensions
4+
///
5+
extension DateFormatter {
6+
7+
/// Default Formatters
8+
///
9+
struct Defaults {
10+
11+
/// Date And Time Formatter
12+
///
13+
static let dateTimeFormatter: DateFormatter = {
14+
let formatter = DateFormatter()
15+
formatter.locale = Locale(identifier: "en_US_POSIX")
16+
formatter.timeZone = TimeZone(identifier: "GMT")
17+
formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH:mm:ss"
18+
return formatter
19+
}()
20+
}
21+
}

WooCommerce/Classes/Model/Order.swift

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct Order: Decodable {
2020
let items: [OrderItem]
2121
let currency: String
2222
let total: String
23-
let notes: [OrderNote]?
23+
var notes: [OrderNote]?
2424
let customerID: Int
2525
let customerNote: String?
2626
let couponLines: [CouponLine]?
@@ -314,14 +314,33 @@ extension OrderItem : Decodable {
314314
// MARK: -
315315
//
316316
struct OrderNote: Decodable {
317-
let date: Date?
318-
let contents: String?
319-
let visibleToCustomers: Bool?
317+
let identifier: Int
318+
let dateCreated: String
319+
let contents: String
320+
let isCustomerNote: Bool
320321

321-
init(date: Date?, contents: String?, visibleToCustomers: Bool?) {
322-
self.date = date
322+
init(identifier: Int, dateCreated: String, contents: String, isCustomerNote: Bool) {
323+
self.identifier = identifier
324+
self.dateCreated = dateCreated
323325
self.contents = contents
324-
self.visibleToCustomers = visibleToCustomers
326+
self.isCustomerNote = isCustomerNote
327+
}
328+
329+
enum OrderNoteStructKeys: String, CodingKey {
330+
case identifier = "id"
331+
case dateCreated = "date_created"
332+
case contents = "note"
333+
case isCustomerNote = "customer_note"
334+
}
335+
336+
init(from decoder: Decoder) throws {
337+
let container = try decoder.container(keyedBy: OrderNoteStructKeys.self)
338+
let identifier = try container.decode(Int.self, forKey: .identifier)
339+
let dateCreated = try container.decode(String.self, forKey: .dateCreated)
340+
let contents = try container.decode(String.self, forKey: .contents)
341+
let isCustomerNote = try container.decode(Bool.self, forKey: .isCustomerNote)
342+
343+
self.init(identifier: identifier, dateCreated: dateCreated, contents: contents, isCustomerNote: isCustomerNote)
325344
}
326345
}
327346

WooCommerce/Classes/Styles/Style.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ protocol Style {
1818
var buttonPrimaryColor: UIColor { get }
1919
var buttonPrimaryHighlightedColor: UIColor { get }
2020
var cellSeparatorColor: UIColor { get }
21+
var wooGreyMid: UIColor { get }
2122
}
2223

2324
// MARK: - WooCommerce's Default Style
@@ -37,6 +38,7 @@ class DefaultStyle: Style {
3738
let buttonPrimaryColor = UIColor(red: 0x96/255.0, green: 0x58/255.0, blue: 0x8A/255.0, alpha: 0xFF/255.0)
3839
let buttonPrimaryHighlightedColor = UIColor(red: 0x6E/255.0, green: 0x29/255.0, blue: 0x67/255.0, alpha: 0xFF/255.0)
3940
let cellSeparatorColor = UIColor.lightGray
41+
let wooGreyMid = UIColor(red: 150.0/255.0, green: 150.0/255.0, blue: 150.0/255.0, alpha: 1.0)
4042
}
4143

4244

@@ -112,4 +114,8 @@ class StyleManager {
112114
static var cellSeparatorColor: UIColor {
113115
return active.cellSeparatorColor
114116
}
117+
118+
static var wooGreyMid: UIColor {
119+
return active.wooGreyMid
120+
}
115121
}

WooCommerce/Classes/ViewModels/OrderDetailsViewModel.swift

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import Foundation
22
import UIKit
3+
import Gridicons
34

45
class OrderDetailsViewModel {
56
private let order: Order
67
private let couponLines: [CouponLine]?
8+
private let notes: [OrderNote]?
79

810
init(order: Order) {
911
self.order = order
1012
self.couponLines = order.couponLines
13+
self.notes = order.notes
1114
}
1215

1316
var summaryTitle: String {
@@ -75,9 +78,7 @@ class OrderDetailsViewModel {
7578
return Double(order.discountTotal) != 0 ? "" + order.currencySymbol + order.discountTotal : nil
7679
}
7780

78-
var shippingLabel: String {
79-
return NSLocalizedString("Shipping", comment: "Shipping label for payment view")
80-
}
81+
let shippingLabel = NSLocalizedString("Shipping", comment: "Shipping label for payment view")
8182

8283
var shippingValue: String {
8384
return order.currencySymbol + order.shippingTotal
@@ -91,9 +92,7 @@ class OrderDetailsViewModel {
9192
return Double(order.totalTax) != 0 ? order.currencySymbol + order.totalTax : nil
9293
}
9394

94-
var totalLabel: String {
95-
return NSLocalizedString("Total", comment: "Total label for payment view")
96-
}
95+
let totalLabel = NSLocalizedString("Total", comment: "Total label for payment view")
9796

9897
var totalValue: String {
9998
return order.currencySymbol + order.total
@@ -103,6 +102,20 @@ class OrderDetailsViewModel {
103102
return NSLocalizedString("Payment of \(totalValue) received via \(order.paymentMethodTitle)", comment: "Payment of <currency symbol><payment total> received via (payment method title)")
104103
}
105104

105+
let addNoteIcon = Gridicon.iconOfType(.addOutline)
106+
107+
let addNoteText = NSLocalizedString("Add a note", comment: "Button text for adding a new order note")
108+
109+
var orderNotes: [OrderNoteViewModel] {
110+
guard let notes = notes else {
111+
return []
112+
}
113+
114+
return notes.map { note in
115+
return OrderNoteViewModel(with: note)
116+
}
117+
}
118+
106119
/// MARK: Private
107120
///
108121
private func summarizeCoupons(from lines: [CouponLine]?) -> String? {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import UIKit
2+
import Gridicons
3+
4+
class OrderNoteViewModel {
5+
let iconImage: UIImage
6+
let iconColor: UIColor
7+
private let formattedDate: Date?
8+
private let jsonDate: String
9+
let statusText: String
10+
let contents: String
11+
12+
init(with orderNote: OrderNote) {
13+
iconImage = Gridicon.iconOfType(.aside)
14+
if orderNote.isCustomerNote {
15+
iconColor = StyleManager.statusPrimaryBoldColor
16+
statusText = NSLocalizedString("Note to customer", comment: "Labels an order note to let user know it's visible to the customer")
17+
} else {
18+
iconColor = StyleManager.wooGreyMid
19+
statusText = NSLocalizedString("Private note", comment: "Labels an order note to let the user know it's private and not seen by the customer")
20+
}
21+
22+
jsonDate = orderNote.dateCreated
23+
let format = DateFormatter.Defaults.dateTimeFormatter
24+
formattedDate = format.date(from: orderNote.dateCreated)
25+
26+
contents = orderNote.contents
27+
}
28+
29+
var dateCreated: String? {
30+
let formatter = DateFormatter()
31+
formatter.dateStyle = .medium
32+
formatter.timeStyle = .short
33+
34+
if let date = formattedDate {
35+
return formatter.string(from: date)
36+
}
37+
return jsonDate
38+
}
39+
}

WooCommerce/Classes/ViewRelated/Orders/OrderDetails/OrderDetailsViewController.swift

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ class OrderDetailsViewController: UIViewController {
4646
let infoRows: [Row] = billingIsHidden ? [.shippingAddress] : [.shippingAddress, .billingAddress, .billingPhone, .billingEmail]
4747
let infoSection = Section(title: NSLocalizedString("CUSTOMER INFORMATION", comment: "Customer info section title"), footer: infoFooter, rows: infoRows)
4848

49+
var noteRows: [Row] = [.addOrderNote]
50+
if let notes = order.notes {
51+
for _ in notes {
52+
noteRows.append(.orderNote)
53+
}
54+
}
55+
let orderNotesSection = Section(title: NSLocalizedString("ORDER NOTES", comment: "Order notes section title"), footer: nil, rows: noteRows)
56+
4957
let paymentSection = Section(title: NSLocalizedString("PAYMENT", comment: "Payment section title"), footer: nil, rows: [.payment])
5058

5159
// FIXME: this is temporary
@@ -54,10 +62,10 @@ class OrderDetailsViewController: UIViewController {
5462
// but order has customerNote as an optional property right now
5563
guard let customerNote = order.customerNote,
5664
!customerNote.isEmpty else {
57-
sections = [summarySection, infoSection, paymentSection]
65+
sections = [summarySection, infoSection, paymentSection, orderNotesSection]
5866
return
5967
}
60-
sections = [summarySection, customerNoteSection, infoSection, paymentSection]
68+
sections = [summarySection, customerNoteSection, infoSection, paymentSection, orderNotesSection]
6169
}
6270

6371
func configureNibs() {
@@ -87,7 +95,7 @@ extension OrderDetailsViewController: UITableViewDataSource {
8795
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
8896
let row = sections[indexPath.section].rows[indexPath.row]
8997
let cell = tableView.dequeueReusableCell(withIdentifier: row.reuseIdentifier, for: indexPath)
90-
configure(cell, for: row)
98+
configure(cell, for: row, at: indexPath)
9199
return cell
92100
}
93101

@@ -136,13 +144,17 @@ extension OrderDetailsViewController: UITableViewDataSource {
136144
extension OrderDetailsViewController: UITableViewDelegate {
137145
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
138146
tableView.deselectRow(at: indexPath, animated: true)
147+
148+
if sections[indexPath.section].rows[indexPath.row] == .addOrderNote {
149+
// TODO: present modal for Add Note screen
150+
}
139151
}
140152
}
141153

142154
// MARK: - Extension
143155
//
144156
extension OrderDetailsViewController {
145-
private func configure(_ cell: UITableViewCell, for row: Row) {
157+
private func configure(_ cell: UITableViewCell, for row: Row, at indexPath: IndexPath) {
146158
switch cell {
147159
case let cell as SummaryTableViewCell:
148160
cell.configure(with: viewModel)
@@ -158,6 +170,10 @@ extension OrderDetailsViewController {
158170
configure(cell, for: .billingEmail)
159171
case let cell as PaymentTableViewCell:
160172
cell.configure(with: viewModel)
173+
case let cell as AddItemTableViewCell:
174+
cell.configure(image: viewModel.addNoteIcon, text: viewModel.addNoteText)
175+
case let cell as OrderNoteTableViewCell where row == .orderNote:
176+
cell.configure(with: viewModel.orderNotes[indexPath.row - 1])
161177
default:
162178
fatalError("Unidentified customer info row type")
163179
}
@@ -282,6 +298,8 @@ private extension OrderDetailsViewController {
282298
case billingAddress
283299
case billingPhone
284300
case billingEmail
301+
case addOrderNote
302+
case orderNote
285303
case payment
286304

287305
var reuseIdentifier: String {
@@ -298,6 +316,10 @@ private extension OrderDetailsViewController {
298316
return BillingDetailsTableViewCell.reuseIdentifier
299317
case .billingEmail:
300318
return BillingDetailsTableViewCell.reuseIdentifier
319+
case .addOrderNote:
320+
return AddItemTableViewCell.reuseIdentifier
321+
case .orderNote:
322+
return OrderNoteTableViewCell.reuseIdentifier
301323
case .payment:
302324
return PaymentTableViewCell.reuseIdentifier
303325
}

0 commit comments

Comments
 (0)